Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion src/anking_notetypes/constants.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import re


NOTETYPE_COPY_RE = r"{notetype_base_name}-[a-zA-Z0-9]{{5}}"
ANKIHUB_NOTETYPE_RE = r"{notetype_base_name} \(.+ / .+\)"

Expand All @@ -8,10 +11,24 @@
r"[\w\W]*"
f"<!-- END {ANKIHUB_NOTE_TYPE_MODIFICATION_STRING} -->"
)
ANKIHUB_TEMPLATE_END_COMMENT = (

ANKIHUB_HTML_END_COMMENT = (
"<!--\n"
"ANKIHUB_END\n"
"Text below this comment will not be modified by AnkiHub or AnKing add-ons.\n"
"Do not edit or remove this comment if you want to protect the content below.\n"
"-->"
)
ANKIHUB_CSS_END_COMMENT = (
"/*\n"
"ANKIHUB_END\n"
"Text below this comment will not be modified by AnkiHub or AnKing add-ons.\n"
"Do not edit or remove this comment if you want to protect the content below.\n"
"*/"
)
ANKIHUB_HTML_END_COMMENT_RE = re.compile(
rf"{re.escape(ANKIHUB_HTML_END_COMMENT)}(?P<text_to_migrate>[\w\W]*)"
)
ANKIHUB_CSS_END_COMMENT_RE = re.compile(
rf"{re.escape(ANKIHUB_CSS_END_COMMENT)}(?P<text_to_migrate>[\w\W]*)"
)
111 changes: 71 additions & 40 deletions src/anking_notetypes/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import re
import time
from copy import deepcopy

from aqt import mw

from .constants import ANKIHUB_TEMPLATE_END_COMMENT, ANKIHUB_TEMPLATE_SNIPPET_RE
from .constants import (
ANKIHUB_CSS_END_COMMENT,
ANKIHUB_CSS_END_COMMENT_RE,
ANKIHUB_HTML_END_COMMENT,
ANKIHUB_HTML_END_COMMENT_RE,
ANKIHUB_TEMPLATE_SNIPPET_RE,
)
from .notetype_setting_definitions import anking_notetype_model

try:
Expand All @@ -28,53 +35,77 @@ def update_notetype_to_newest_version(

new_model = adjust_field_ords(model, new_model)

# the order is important here
# the end comment must be added after the ankihub snippet
retain_ankihub_modifications_to_templates(model, new_model)
retain_content_below_ankihub_end_comment_or_add_end_comment(model, new_model)
new_model = _retain_ankihub_modifications(model, new_model)

model.update(new_model)


def retain_ankihub_modifications_to_templates(
def _retain_ankihub_modifications(
old_model: "NotetypeDict", new_model: "NotetypeDict"
) -> "NotetypeDict":
updated_templates = []
for old_template, new_template in zip(old_model["tmpls"], new_model["tmpls"]):
for template_type in ["qfmt", "afmt"]:
m = re.search(ANKIHUB_TEMPLATE_SNIPPET_RE, old_template[template_type])
if not m:
continue

new_template[template_type] = (
new_template[template_type].rstrip("\n ") + "\n\n" + m.group(0)
updated_template = deepcopy(new_template)
for template_side in ["qfmt", "afmt"]:
updated_template[template_side] = _updated_note_type_content(
old_template[template_side],
new_template[template_side],
content_type="html",
)

return new_model


def retain_content_below_ankihub_end_comment_or_add_end_comment(
old_model: "NotetypeDict", new_model: "NotetypeDict"
) -> "NotetypeDict":
# will add the end comment if it doesn't exist
for old_template, new_template in zip(old_model["tmpls"], new_model["tmpls"]):
for template_type in ["qfmt", "afmt"]:
m = re.search(
rf"{ANKIHUB_TEMPLATE_END_COMMENT}[\w\W]*",
old_template[template_type],
)
if m:
new_template[template_type] = (
new_template[template_type].rstrip("\n ") + "\n\n" + m.group(0)
)
else:
new_template[template_type] = (
new_template[template_type].rstrip("\n ")
+ "\n\n"
+ ANKIHUB_TEMPLATE_END_COMMENT
+ "\n\n"
)

return new_model
updated_templates.append(updated_template)

result = deepcopy(new_model)
result["tmpls"] = updated_templates

result["css"] = _updated_note_type_content(
old_content=old_model["css"],
new_content=new_model["css"],
content_type="css",
)

return result


def _updated_note_type_content(
old_content: str,
new_content: str,
content_type: str,
) -> str:
"""Returns new_content with preserved ankihub modifications and
preserved content below the ankihub end comment.

Args:
old_content: Original content to preserve ankihub modifications and custom additions from
new_content: New base content to use
content_type: Either "html" or "css" to determine comment style
"""
if content_type == "html":
end_comment = ANKIHUB_HTML_END_COMMENT
end_comment_pattern = ANKIHUB_HTML_END_COMMENT_RE
else:
end_comment = ANKIHUB_CSS_END_COMMENT
end_comment_pattern = ANKIHUB_CSS_END_COMMENT_RE

snippet_match = re.search(ANKIHUB_TEMPLATE_SNIPPET_RE, old_content)
ankihub_snippet = snippet_match.group() if snippet_match else ""

text_to_migrate_match = re.search(end_comment_pattern, old_content)
text_to_migrate = (
text_to_migrate_match.group("text_to_migrate") if text_to_migrate_match else ""
)

# Remove end comment and content below it.
# It will be added back below.
result = re.sub(end_comment_pattern, "", new_content)

return (
result.rstrip("\n ")
+ (f"\n{ankihub_snippet}" if ankihub_snippet else "")
+ "\n\n"
+ end_comment
+ "\n"
+ text_to_migrate.strip("\n ")
)


def adjust_field_ords(
Expand Down