diff --git a/.gitignore b/.gitignore index 8edad8791ad08a32febc5e3dd167557e737164b9..406c7f3af33e3247873f2458a5c1ff7cbbc16f9c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,9 @@ __pycache__ .vscode .build-cache .venv -artifacts +/artifacts *.d.mk -templates +/templates /*.apkg hanzi-data .data-test-ok diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6865d465db36274abbb85caec3c22ed7ddfa0ac3..4e3030bf89d1a8652ff83e40d757a9331c2c43c0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,8 +27,7 @@ build: - echo RELEASE_TAR_URL=$RELEASE_TAR_URL >> build.env artifacts: paths: - - sinologie-anki-pack-* - - ANNOUNCEMENT + - card-templates-*.tar.gz reports: dotenv: build.env @@ -48,7 +47,7 @@ release-package-json-version-as-git-tag: - if [ -z "$NPM_VERSION_GIT_TAG" ]; then - echo adding git tag for first commit on main with NPM version ${NPM_VERSION} - git remote remove origin - - git remote add origin https://oauth:${REPOSITORY_ACCESS_TOKEN}@gitlab.phaidra.org/kartenaale/sinologie-anki-pack.git + - git remote add origin https://oauth:${REPOSITORY_ACCESS_TOKEN}@gitlab.phaidra.org/kartenaale/card-templates.git - git config user.email Cao Cao - git config user.name cao.cao@ci.kartenaale - git tag -a $NPM_VERSION -m "Release $NPM_VERSION" @@ -70,9 +69,12 @@ create-gitlab-release: GIT_STRATEGY: none # we don't need anything in node_modules or python, so don't fetch the cache cache: [] + script: + - echo Creating GitLab release… release: tag_name: '$CI_COMMIT_TAG' name: 'Card Templates $CI_COMMIT_TAG' + description: '$RELEASE_TAR is ready for download.' assets: links: - name: '$RELEASE_TAR' diff --git a/src/templates/bijective/.template-spec.yaml b/src/templates/bijective/.template-spec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ed45670a2d8a25a4528788b12ec8e6095e18541a --- /dev/null +++ b/src/templates/bijective/.template-spec.yaml @@ -0,0 +1,16 @@ +template_version: 2024-02-28 22:00:00+00:00 + +note_type: + id: 2024-01-05 03:00:00+00:00 + name: Bijection + fields: + - A + - B + +card_types: +- name: Forward + template: forward +- name: Backward + template: backward + +resource_paths: [] diff --git a/src/templates/bijective/backward/back.html b/src/templates/bijective/backward/back.html new file mode 100644 index 0000000000000000000000000000000000000000..84534fbef4bf17dc733bf2504a2833cf24a1529d --- /dev/null +++ b/src/templates/bijective/backward/back.html @@ -0,0 +1,23 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back bijective-backward-back"> + <div class="bijective-answer"> + {{A}} + </div> + + <include src="src/components/notice/notice.html"></include> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/bijective/backward/front.html b/src/templates/bijective/backward/front.html new file mode 100644 index 0000000000000000000000000000000000000000..8fb070ca68fe2b6782da088c8d6be88c61c0c954 --- /dev/null +++ b/src/templates/bijective/backward/front.html @@ -0,0 +1,29 @@ +<style> + @import url(../../../components/global.css); + @import url(../../../components/facts.css); +</style> + +<div class="exercise front bijective-backward-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + + <div class="prompt bijective-question"> + {{B}} + </div> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> \ No newline at end of file diff --git a/src/templates/bijective/forward/back.html b/src/templates/bijective/forward/back.html new file mode 100644 index 0000000000000000000000000000000000000000..afbae1a920ec242f9d2fed054e70b5a6d895e16a --- /dev/null +++ b/src/templates/bijective/forward/back.html @@ -0,0 +1,23 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back bijective-forward-back"> + <div class="bijective-answer"> + {{B}} + </div> + + <include src="src/components/notice/notice.html"></include> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/bijective/forward/front.html b/src/templates/bijective/forward/front.html new file mode 100644 index 0000000000000000000000000000000000000000..6552410c728b94ee4edcb7f7bbbe9a20fd07e714 --- /dev/null +++ b/src/templates/bijective/forward/front.html @@ -0,0 +1,29 @@ +<style> + @import url(../../../components/global.css); + @import url(../../../components/facts.css); +</style> + +<div class="exercise front bijective-forward-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + + <div class="prompt bijective-question"> + {{A}} + </div> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> \ No newline at end of file diff --git a/src/templates/facts/.template-spec.yaml b/src/templates/facts/.template-spec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fe384c1e79bf439cf2299d42295600564245698c --- /dev/null +++ b/src/templates/facts/.template-spec.yaml @@ -0,0 +1,14 @@ +template_version: 2024-02-28 22:00:00+00:00 + +note_type: + id: 2024-01-04 03:00:00+00:00 + name: Facts + fields: + - Front + - Back + +card_types: +- name: Q/A + template: q_a + +resource_paths: [] diff --git a/src/templates/facts/q_a/back.html b/src/templates/facts/q_a/back.html new file mode 100644 index 0000000000000000000000000000000000000000..1ac8a0788f6fcbe64b2bd300a560d7e6648180a2 --- /dev/null +++ b/src/templates/facts/q_a/back.html @@ -0,0 +1,23 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back facts-q-a-back"> + <div class="facts-answer"> + {{Back}} + </div> + + <include src="src/components/notice/notice.html"></include> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/facts/q_a/front.html b/src/templates/facts/q_a/front.html new file mode 100644 index 0000000000000000000000000000000000000000..9dce46e5f30d7eca54411614df3c55003fc2b7d2 --- /dev/null +++ b/src/templates/facts/q_a/front.html @@ -0,0 +1,29 @@ +<style> + @import url(../../../components/global.css); + @import url(../../../components/facts.css); +</style> + +<div class="exercise front facts-q-a-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + + <div class="prompt facts-question"> + {{Front}} + </div> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> \ No newline at end of file diff --git a/src/templates/hanzi/.template-spec.yaml b/src/templates/hanzi/.template-spec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0908f3094ee9c9766d2a2330c2fa076da85480a9 --- /dev/null +++ b/src/templates/hanzi/.template-spec.yaml @@ -0,0 +1,26 @@ +template_version: 2024-03-20 10:00:00+00:00 + +note_type: + id: 2024-02-21 12:00:00+00:00 + name: Hanzi + fields: + - Keyword + - Keyword type + - Notes (Front) + - Hanzi + - Book + - Lesson + - Frame + - Order (Sequential) + - Order (Parallel) + - resources + - Notes (Back) + - Traditional + - Simplified + +card_types: +- name: Schreiben + template: write + +resource_paths: +- '{{BUILD_PREFIX}}hanzi-data' diff --git a/src/templates/hanzi/write/back.html b/src/templates/hanzi/write/back.html new file mode 100644 index 0000000000000000000000000000000000000000..b176010e465ffba032bb66d8f77781403597df87 --- /dev/null +++ b/src/templates/hanzi/write/back.html @@ -0,0 +1,28 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back hanzi-write-back"> + <dl class="translations"> + <dt>Stroke order</dt> + <dd class="strichfolge-animation is-large{{#Traditional}} is-traditional{{/Traditional}}">{{text:Hanzi}}</dd> + <dt>Notes</dt> + <dd>{{Notes (Back)}}</dd> + <dt>Print form</dt> + <dd><span class="hanzi-print is-large">{{Hanzi}}</span></dd> + </dl> + + <include src="src/components/notice/notice.html"></include> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/hanzi/write/front.html b/src/templates/hanzi/write/front.html new file mode 100644 index 0000000000000000000000000000000000000000..f58e910788efc3e0ca0a7c49d4d243ffac4cb141 --- /dev/null +++ b/src/templates/hanzi/write/front.html @@ -0,0 +1,36 @@ +{{#Hanzi}}{{#Keyword}} +<style> + @import url(../../../components/global.css); + @import url(../../../components/heisig.css); +</style> + +<div class="exercise front hanzi-write-front"> + <header class="card-info"> + <aside class="exercise-kind"> + {{Frame}} + </aside> + </header> + + <dl class="prompt translations"> + <dt>Key word</dt> + <dd> + <span class="hanzi-keyword">{{Keyword}}</span> + {{#Keyword type}} + <span class="hanzi-keyword-type">({{Keyword type}})</span> + {{/Keyword type}} + </dd> + <dt>Notes</dt> + <dd>{{Notes (Front)}}</dd> + </dl> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> +{{/Keyword}}{{/Hanzi}} \ No newline at end of file diff --git a/src/templates/index.html b/src/templates/index.html new file mode 100644 index 0000000000000000000000000000000000000000..700a6125d0dd74ff316a4999a83d204295f79391 --- /dev/null +++ b/src/templates/index.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <meta charset="UTF-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Anki Template Hanyu Overview</title> +</head> + +<body> + <h1>Overview</h1> + + <h2>templates/bijective</h2> + <h3>Forward</h3> + <h4>Front</h4> + <a href="bijective/backward/front.html">forward/front.html</a> + <h4>Back</h4> + <a href="bijective/backward/back.html">forward/back.html</a> + <h3>Backward</h3> + <h4>Front</h4> + <a href="bijective/forward/front.html">backward/front.html</a> + <h4>Back</h4> + <a href="bijective/forward/back.html">backward/back.html</a> + + <h2>templates/facts</h2> + <h3>Q/A</h3> + <h4>Front</h4> + <a href="facts/q_a/front.html">q_a/front.html</a> + <h4>Back</h4> + <a href="facts/q_a/back.html"> q_a/back.html</a> + + <h2>templates/hanzi</h2> + <h3>Write</h3> + <h4>Front</h4> + <a href="hanzi/write/front.html">write/front.html</a> + <h4>Back</h4> + <a href="hanzi/write/back.html">write/back.html</a> + + <h2>templates/molaoshi</h2> + <h3>Hear</h3> + <h4>Front</h4> + <a href="molaoshi/hear/front.html">hear/front.html</a> + <h4>Back</h4> + <a href="molaoshi/hear/back.html">hear/back.html</a> + + <h3>Read Hanzi</h3> + <h4>Front</h4> + <a href="molaoshi/read_hanzi/front.html">read_hanzi/front.html</a> + <h4>Back</h4> + <a href="molaoshi/read_hanzi/back.html">read_hanzi/back.html</a> + + <h3>Read Hanzi (traditional)</h3> + <h4>Front</h4> + <a href="molaoshi/read_hanzi_traditional/front.html">read_hanzi_traditional/front.html</a> + <h4>Back</h4> + <a href="molaoshi/read_hanzi_traditional/back.html">read_hanzi_traditional/back.html</a> + + <h3>Read Pinyin</h3> + <h4>Front</h4> + <a href="molaoshi/read_pinyin/front.html">read_pinyin/front.html</a> + <h4>Back</h4> + <a href="molaoshi/read_pinyin/back.html">read_pinyin/back.html</a> + + <h3>Speak</h3> + <h4>Front</h4> + <a href="molaoshi/speak/front.html">speak/front.html</a> + <h4>Back</h4> + <a href="molaoshi/speak/back.html">speak/back.html</a> + + <h3>Write</h3> + <h4>Front</h4> + <a href="molaoshi/write/front.html">write/front.html</a> + <h4>Back</h4> + <a href="molaoshi/write/back.html">write/back.html</a> + + <h3>Identify radical</h3> + <h4>Front</h4> + <a href="molaoshi/identify_radical/front.html">identify_radical/front.html</a> + <h4>Back</h4> + <a href="molaoshi/identify_radical/back.html">identify_radical/back.html</a> + + <h3>Identify radical (traditional)</h3> + <h4>Front</h4> + <a href="molaoshi/identify_radical_traditional/front.html">identify_radical_traditional/front.html</a> + <h4>Back</h4> + <a href="molaoshi/identify_radical_traditional/back.html">identify_radical_traditional/back.html</a> +</body> + +</html> \ No newline at end of file diff --git a/src/templates/molaoshi/.template-spec.yaml b/src/templates/molaoshi/.template-spec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5f982c729ae2c0b918880490d4f06b90c13f0568 --- /dev/null +++ b/src/templates/molaoshi/.template-spec.yaml @@ -0,0 +1,45 @@ +template_version: 2024-06-14 12:00:00+00:00 + +note_type: + id: 2024-02-20 12:00:00+00:00 + name: Vokabeln + fields: + - Deutsch + - 简体字 + - 繁體字 + - Pīnyīn + - Bemerkungen + - Beispiele + - Lektion + # this is only necessary to make explicit to keep the later added fields + # id contents + - resources + - Bemerkungen (Vorderseite) + - Standardaussprache + - Audioaufnahme + - Radikal finden anlegen + - Radikal finden (繁體字) anlegen + - Schreiben anlegen + - Zhuyin + - Lesen (繁體字) anlegen + +card_types: +- name: Hören + template: hear +- name: Lesen (Pīnyīn) + template: read_pinyin +- name: Lesen (简体字) + template: read_hanzi +- name: Lesen (繁體字) + template: read_hanzi_traditional +- name: Schreiben + template: write +- name: Sprechen + template: speak +- name: Radikal finden (简体字) + template: identify_radical +- name: Radikal finden (繁體字) + template: identify_radical_traditional + +resource_paths: +- '{{BUILD_PREFIX}}hanzi-data' diff --git a/src/templates/molaoshi/hear/back.html b/src/templates/molaoshi/hear/back.html new file mode 100644 index 0000000000000000000000000000000000000000..a32ec6f63bf33e981ed055582dc2699bd5198b39 --- /dev/null +++ b/src/templates/molaoshi/hear/back.html @@ -0,0 +1,68 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back anki-template-hanyu-hear-back"> + <dl class="translations"> + <dt>Pīnyīn</dt> + <dd>{{Pīnyīn}}</dd> + <dt>Deutsch</dt> + <dd>{{Deutsch}}</dd> + <dt>简体字</dt> + <dd> + <span class="hanzi-print">{{简体字}}</span> + <div class="strichfolge-animation" no-animate="true" highlight-radical="true"> + {{text:简体字}} + </div> + </dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen}}</dd> + <dt>Beispiele</dt> + <dd>{{Beispiele}}</dd> + <details class="answer-details"> + <summary> + <span class="answer-details-more">Mehr…</span> + <span class="answer-details-less">Weniger…</span> + </summary> + {{#繁體字}} + <dt>繁體字</dt> + <dd> + <span class="hanzi-print">{{繁體字}}</span> + <div class="strichfolge-animation is-traditional" no-animate="true" highlight-radical="true"> + {{text:繁體字}} + </div> + </dd> + {{/繁體字}} + <dt>Radikal (简体字)</dt> + <dd> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation" no-animate="true"> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical"></span> + </div> + </dd> + {{#繁體字}} + <dt>Radikal (繁體字)</dt> + <dd> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation is-traditional" no-animate="true"> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical"></span> + </div> + </dd> + {{/繁體字}} + </details> + </dl> + + <include src="src/components/notice/notice.html"></include> +</div> + +<!-- Repeat only relevant text on the back side on AnkiDroid, not all of it --> +<tts style="display: none" service="android" voice="zh_CN">{{text:简体字}}</tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/molaoshi/hear/front.html b/src/templates/molaoshi/hear/front.html new file mode 100644 index 0000000000000000000000000000000000000000..6d7b05d3ad1767c89f7ba114455ea4b6f99682d1 --- /dev/null +++ b/src/templates/molaoshi/hear/front.html @@ -0,0 +1,45 @@ +{{#Standardaussprache}} +<style> + @import url(../../../components/global.css); +</style> + +<div class="exercise front anki-template-hanyu-hear-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + </header> + + <dl class="prompt translations"> + <dt>汉语</dt> + <dd id="t2s-player-container" class="t2s-player-container"> + <div class="anki-droid-player"> + <tts style="display: none" service="android" voice="zh_CN"> + {{text:Standardaussprache}} + </tts> + </div> + <div class="anki-web-player"> + {{text:Standardaussprache}} + </div> + <div class="anki-builtin-player"> + {{tts zh_CN:Standardaussprache}} + </div> + </dd> + <dt>Aufnahme</dt> + <dd>{{Audioaufnahme}}</dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen (Vorderseite)}}</dd> + </dl> +</div> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> +{{/Standardaussprache}} \ No newline at end of file diff --git a/src/templates/molaoshi/identify_radical/back.html b/src/templates/molaoshi/identify_radical/back.html new file mode 100644 index 0000000000000000000000000000000000000000..0d1a17ecb421718485288e2dd8bfa750e56f1128 --- /dev/null +++ b/src/templates/molaoshi/identify_radical/back.html @@ -0,0 +1,35 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back radicals-identify-back"> + <dl class="translations"> + <dt>Radikal (简体字)</dt> + <dd> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation" no-animate="true"> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical"></span> + </div> + </dd> + <dt>Name (中文)</dt> + <dd hanzi-data="{{text:简体字}}" hanzi-prop="radicalMeaningZh"></dd> + <dt>Name (Deutsch)</dt> + <dd hanzi-data="{{text:简体字}}" hanzi-prop="radicalMeaningDe"></dd> + <dt>Strichzahl</dt> + <dd hanzi-data="{{text:简体字}}" hanzi-prop="count"></dd> + </dl> + + <include src="src/components/notice/notice.html"></include> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/molaoshi/identify_radical/front.html b/src/templates/molaoshi/identify_radical/front.html new file mode 100644 index 0000000000000000000000000000000000000000..e0302ce0df617461cbbfc73f7d96eaf1e4de6d4f --- /dev/null +++ b/src/templates/molaoshi/identify_radical/front.html @@ -0,0 +1,39 @@ +{{#简体字}}{{#Radikal finden anlegen}} +<style> + @import url(../../../components/global.css); +</style> + +<div class="exercise front radicals-identify-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + </header> + + <dl class="prompt translations"> + <dt>简体字</dt> + <dd> + <span class="hanzi-print">{{简体字}}</span> + <div class="strichfolge-animation" no-animate="true" highlight-radical="answer"> + {{text:简体字}} + </div> + </dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen (Vorderseite)}}</dd> + </dl> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> +{{/Radikal finden anlegen}}{{/简体字}} \ No newline at end of file diff --git a/src/templates/molaoshi/identify_radical_traditional/back.html b/src/templates/molaoshi/identify_radical_traditional/back.html new file mode 100644 index 0000000000000000000000000000000000000000..7a642befa6dfc17535bd8a3ccd20f3cb490a1449 --- /dev/null +++ b/src/templates/molaoshi/identify_radical_traditional/back.html @@ -0,0 +1,35 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back radicals-identify-back"> + <dl class="translations"> + <dt>Radikal (繁體字)</dt> + <dd> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation is-traditional" no-animate="true"> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical"></span> + </div> + </dd> + <dt>Name (中文)</dt> + <dd hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radicalMeaningZh"></dd> + <dt>Name (Deutsch)</dt> + <dd hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radicalMeaningDe"></dd> + <dt>Strichzahl</dt> + <dd hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="count"></dd> + </dl> + + <include src="src/components/notice/notice.html"></include> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/molaoshi/identify_radical_traditional/front.html b/src/templates/molaoshi/identify_radical_traditional/front.html new file mode 100644 index 0000000000000000000000000000000000000000..ea10b1cae3adc893ae9c63295f815b1e35ea3647 --- /dev/null +++ b/src/templates/molaoshi/identify_radical_traditional/front.html @@ -0,0 +1,39 @@ +{{#繁體字}}{{#Radikal finden (繁體字) anlegen}} +<style> + @import url(../../../components/global.css); +</style> + +<div class="exercise front radicals-identify-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + </header> + + <dl class="prompt translations"> + <dt>繁體字</dt> + <dd> + <span class="hanzi-print">{{繁體字}}</span> + <div class="strichfolge-animation is-traditional" no-animate="true" highlight-radical="answer"> + {{text:繁體字}} + </div> + </dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen (Vorderseite)}}</dd> + </dl> +</div> + +<!-- Suppress speech output on AnkiDroid if globally enabled --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> +{{/Radikal finden (繁體字) anlegen}}{{/繁體字}} \ No newline at end of file diff --git a/src/templates/molaoshi/read_hanzi/back.html b/src/templates/molaoshi/read_hanzi/back.html new file mode 100644 index 0000000000000000000000000000000000000000..a16bcfd82015db00e0c4a68db99b5cd33cca6372 --- /dev/null +++ b/src/templates/molaoshi/read_hanzi/back.html @@ -0,0 +1,76 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back anki-template-hanyu-read-hanzi-back"> + <dl class="translations"> + <dt>Pīnyīn</dt> + <dd>{{Pīnyīn}}</dd> + <dt>Deutsch</dt> + <dd>{{Deutsch}}</dd> + {{#Standardaussprache}} + <dt class="t2s-player-heading">汉语</dt> + <dd id="t2s-player-container" class="t2s-player-container"> + <div class="anki-droid-player"> + <tts style="display: none" service="android" voice="zh_CN"> + {{text:Standardaussprache}} + </tts> + </div> + <div class="anki-web-player"> + {{text:Standardaussprache}} + </div> + <div class="anki-builtin-player"> + {{tts zh_CN:Standardaussprache}} + </div> + </dd> + {{/Standardaussprache}} + <dt>Aufnahme</dt> + <dd>{{Audioaufnahme}}</dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen}}</dd> + <dt>Beispiele</dt> + <dd>{{Beispiele}}</dd> + <details class="answer-details"> + <summary> + <span class="answer-details-more">Mehr…</span> + <span class="answer-details-less">Weniger…</span> + </summary> + {{#繁體字}} + <dt>繁體字</dt> + <dd> + <span class="hanzi-print">{{繁體字}}</span> + <div class="strichfolge-animation is-traditional" no-animate="true" highlight-radical="true"> + {{text:繁體字}} + </div> + </dd> + {{/繁體字}} + <dt>Radikal (简体字)</dt> + <dd> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation" no-animate="true"> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical"></span> + </div> + </dd> + {{#繁體字}} + <dt>Radikal (繁體字)</dt> + <dd> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation is-traditional" no-animate="true"> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical"></span> + </div> + </dd> + {{/繁體字}} + </details> + </dl> + + <include src="src/components/notice/notice.html"></include> +</div> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/molaoshi/read_hanzi/front.html b/src/templates/molaoshi/read_hanzi/front.html new file mode 100644 index 0000000000000000000000000000000000000000..2238436e1bfafb3dacff27a7a17ffe88131c441c --- /dev/null +++ b/src/templates/molaoshi/read_hanzi/front.html @@ -0,0 +1,39 @@ +{{#简体字}} +<style> + @import url(../../../components/global.css); +</style> + +<div class="exercise front anki-template-hanyu-read-hanzi-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + </header> + + <dl class="prompt translations"> + <dt>简体字</dt> + <dd> + <span class="hanzi-print">{{简体字}}</span> + <div class="strichfolge-animation" no-animate="true" highlight-radical="answer"> + {{text:简体字}} + </div> + </dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen (Vorderseite)}}</dd> + </dl> +</div> + +<!-- Suppress speech output on AnkiDroid until card flipped --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> +{{/简体字}} \ No newline at end of file diff --git a/src/templates/molaoshi/read_hanzi_traditional/back.html b/src/templates/molaoshi/read_hanzi_traditional/back.html new file mode 100644 index 0000000000000000000000000000000000000000..e95f0c09f4724f97995ec50a8f97f1cb7687c350 --- /dev/null +++ b/src/templates/molaoshi/read_hanzi_traditional/back.html @@ -0,0 +1,76 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back anki-template-hanyu-read-hanzi-back"> + <dl class="translations"> + <dt>Pīnyīn</dt> + <dd>{{Pīnyīn}}</dd> + <dt>Deutsch</dt> + <dd>{{Deutsch}}</dd> + {{#Standardaussprache}} + <dt class="t2s-player-heading">汉语</dt> + <dd id="t2s-player-container" class="t2s-player-container"> + <div class="anki-droid-player"> + <tts style="display: none" service="android" voice="zh_CN"> + {{text:Standardaussprache}} + </tts> + </div> + <div class="anki-web-player"> + {{text:Standardaussprache}} + </div> + <div class="anki-builtin-player"> + {{tts zh_CN:Standardaussprache}} + </div> + </dd> + {{/Standardaussprache}} + <dt>Aufnahme</dt> + <dd>{{Audioaufnahme}}</dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen}}</dd> + <dt>Beispiele</dt> + <dd>{{Beispiele}}</dd> + <details class="answer-details"> + <summary> + <span class="answer-details-more">Mehr…</span> + <span class="answer-details-less">Weniger…</span> + </summary> + {{#简体字}} + <dt>简体字</dt> + <dd> + <span class="hanzi-print">{{简体字}}</span> + <div class="strichfolge-animation" no-animate="true"> + {{text:简体字}} + </div> + </dd> + {{/简体字}} + <dt>Radikal (繁體字)</dt> + <dd> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation is-traditional" no-animate="true"> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical"></span> + </div> + </dd> + {{#简体字}} + <dt>Radikal (简体字)</dt> + <dd> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation" no-animate="true"> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical"></span> + </div> + </dd> + {{/简体字}} + </details> + </dl> + + <include src="src/components/notice/notice.html"></include> +</div> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/molaoshi/read_hanzi_traditional/front.html b/src/templates/molaoshi/read_hanzi_traditional/front.html new file mode 100644 index 0000000000000000000000000000000000000000..99cfaf7746d092c5e7b7e54a9746cf83d98820bc --- /dev/null +++ b/src/templates/molaoshi/read_hanzi_traditional/front.html @@ -0,0 +1,39 @@ +{{#Lesen (繁體字) anlegen}}{{#繁體字}} +<style> + @import url(../../../components/global.css); +</style> + +<div class="exercise front anki-template-hanyu-read-hanzi-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + </header> + + <dl class="prompt translations"> + <dt>繁體字</dt> + <dd> + <span class="hanzi-print">{{繁體字}}</span> + <div class="strichfolge-animation is-traditional" no-animate="true" highlight-radical="answer"> + {{text:繁體字}} + </div> + </dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen (Vorderseite)}}</dd> + </dl> +</div> + +<!-- Suppress speech output on AnkiDroid until card flipped --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> +{{/繁體字}}{{/Lesen (繁體字) anlegen}} \ No newline at end of file diff --git a/src/templates/molaoshi/read_pinyin/back.html b/src/templates/molaoshi/read_pinyin/back.html new file mode 100644 index 0000000000000000000000000000000000000000..71d713190f6f8922fb89900810f4e786aeaa8caf --- /dev/null +++ b/src/templates/molaoshi/read_pinyin/back.html @@ -0,0 +1,81 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back anki-template-hanyu-read-pinyin-back"> + <dl class="translations"> + <dt>Deutsch</dt> + <dd>{{Deutsch}}</dd> + <dt>简体字</dt> + <dd> + <span class="hanzi-print">{{简体字}}</span> + <div class="strichfolge-animation" no-animate="true" highlight-radical="true"> + {{text:简体字}} + </div> + </dd> + {{#Standardaussprache}} + <dt class="t2s-player-heading">汉语</dt> + <dd id="t2s-player-container" class="t2s-player-container"> + <div class="anki-droid-player"> + <tts style="display: none" service="android" voice="zh_CN"> + {{text:Standardaussprache}} + </tts> + </div> + <div class="anki-web-player"> + {{text:Standardaussprache}} + </div> + <div class="anki-builtin-player"> + {{tts zh_CN:Standardaussprache}} + </div> + </dd> + {{/Standardaussprache}} + <dt>Aufnahme</dt> + <dd>{{Audioaufnahme}}</dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen}}</dd> + <dt>Beispiele</dt> + <dd>{{Beispiele}}</dd> + <details class="answer-details"> + <summary> + <span class="answer-details-more">Mehr…</span> + <span class="answer-details-less">Weniger…</span> + </summary> + {{#繁體字}} + <dt>繁體字</dt> + <dd> + <span class="hanzi-print">{{繁體字}}</span> + <div class="strichfolge-animation is-traditional" no-animate="true" highlight-radical="true"> + {{text:繁體字}} + </div> + </dd> + {{/繁體字}} + <dt>Radikal (简体字)</dt> + <dd> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation" no-animate="true"> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical"></span> + </div> + </dd> + {{#繁體字}} + <dt>Radikal (繁體字)</dt> + <dd> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation is-traditional" no-animate="true"> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical"></span> + </div> + </dd> + {{/繁體字}} + </details> + </dl> + + <include src="src/components/notice/notice.html"></include> +</div> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/molaoshi/read_pinyin/front.html b/src/templates/molaoshi/read_pinyin/front.html new file mode 100644 index 0000000000000000000000000000000000000000..767425794c210bc5a0c31a65f396e0d0e2d579d0 --- /dev/null +++ b/src/templates/molaoshi/read_pinyin/front.html @@ -0,0 +1,34 @@ +{{#Pīnyīn}} +<style> + @import url(../../../components/global.css); +</style> + +<div class="exercise front anki-template-hanyu-read-pinyin-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + </header> + + <dl class="prompt translations"> + <dt>Pīnyīn</dt> + <dd>{{Pīnyīn}}</dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen (Vorderseite)}}</dd> + </dl> +</div> + +<!-- Suppress speech output on AnkiDroid until card flipped --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> +{{/Pīnyīn}} \ No newline at end of file diff --git a/src/templates/molaoshi/speak/back.html b/src/templates/molaoshi/speak/back.html new file mode 100644 index 0000000000000000000000000000000000000000..b80aea9a7b0f06770e7a3c6d5944612bb0a5e33a --- /dev/null +++ b/src/templates/molaoshi/speak/back.html @@ -0,0 +1,81 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back anki-template-hanyu-speak-back"> + <dl class="translations"> + <dt>Pīnyīn</dt> + <dd>{{Pīnyīn}}</dd> + <dt>简体字</dt> + <dd> + <span class="hanzi-print">{{简体字}}</span> + <div class="strichfolge-animation" no-animate="true" highlight-radical="true"> + {{text:简体字}} + </div> + </dd> + {{#Standardaussprache}} + <dt class="t2s-player-heading">汉语</dt> + <dd id="t2s-player-container" class="t2s-player-container"> + <div class="anki-droid-player"> + <tts style="display: none" service="android" voice="zh_CN"> + {{text:Standardaussprache}} + </tts> + </div> + <div class="anki-web-player"> + {{text:Standardaussprache}} + </div> + <div class="anki-builtin-player"> + {{tts zh_CN:Standardaussprache}} + </div> + </dd> + {{/Standardaussprache}} + <dt>Aufnahme</dt> + <dd>{{Audioaufnahme}}</dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen}}</dd> + <dt>Beispiele</dt> + <dd>{{Beispiele}}</dd> + <details class="answer-details"> + <summary> + <span class="answer-details-more">Mehr…</span> + <span class="answer-details-less">Weniger…</span> + </summary> + {{#繁體字}} + <dt>繁體字</dt> + <dd> + <span class="hanzi-print">{{繁體字}}</span> + <div class="strichfolge-animation is-traditional" no-animate="true" highlight-radical="true"> + {{text:繁體字}} + </div> + </dd> + {{/繁體字}} + <dt>Radikal (简体字)</dt> + <dd> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation" no-animate="true"> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical"></span> + </div> + </dd> + {{#繁體字}} + <dt>Radikal (繁體字)</dt> + <dd> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation is-traditional" no-animate="true"> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical"></span> + </div> + </dd> + {{/繁體字}} + </details> + </dl> + + <include src="src/components/notice/notice.html"></include> +</div> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/molaoshi/speak/front.html b/src/templates/molaoshi/speak/front.html new file mode 100644 index 0000000000000000000000000000000000000000..a93e52ec72911078a60d4a58a91fa1f82cacb669 --- /dev/null +++ b/src/templates/molaoshi/speak/front.html @@ -0,0 +1,34 @@ +{{#Deutsch}} +<style> + @import url(../../../components/global.css); +</style> + +<div class="exercise front anki-template-hanyu-speak-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + </header> + + <dl class="prompt translations"> + <dt>Deutsch</dt> + <dd>{{Deutsch}}</dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen (Vorderseite)}}</dd> + </dl> +</div> + +<!-- Suppress speech output on AnkiDroid until card flipped --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> +{{/Deutsch}} \ No newline at end of file diff --git a/src/templates/molaoshi/write/back.html b/src/templates/molaoshi/write/back.html new file mode 100644 index 0000000000000000000000000000000000000000..6417876fcdb6ba973116beaa957fc184cc5d7695 --- /dev/null +++ b/src/templates/molaoshi/write/back.html @@ -0,0 +1,81 @@ +<div class="front-side-on-back"> + {{FrontSide}} +</div> + +<hr id="answer"> + +<div class="exercise back anki-template-hanyu-write-back"> + <dl class="translations"> + <dt>简体字</dt> + <dd> + <span class="hanzi-print">{{简体字}}</span> + <div class="strichfolge-animation" highlight-radical="true"> + {{text:简体字}} + </div> + </dd> + <dt>Pīnyīn</dt> + <dd>{{Pīnyīn}}</dd> + {{#Standardaussprache}} + <dt class="t2s-player-heading">汉语</dt> + <dd id="t2s-player-container" class="t2s-player-container"> + <div class="anki-droid-player"> + <tts style="display: none" service="android" voice="zh_CN"> + {{text:Standardaussprache}} + </tts> + </div> + <div class="anki-web-player"> + {{text:Standardaussprache}} + </div> + <div class="anki-builtin-player"> + {{tts zh_CN:Standardaussprache}} + </div> + </dd> + {{/Standardaussprache}} + <dt>Aufnahme</dt> + <dd>{{Audioaufnahme}}</dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen}}</dd> + <dt>Beispiele</dt> + <dd>{{Beispiele}}</dd> + <details class="answer-details"> + <summary> + <span class="answer-details-more">Mehr…</span> + <span class="answer-details-less">Weniger…</span> + </summary> + {{#繁體字}} + <dt>繁體字</dt> + <dd> + <span class="hanzi-print">{{繁體字}}</span> + <div class="strichfolge-animation is-traditional" highlight-radical="true"> + {{text:繁體字}} + </div> + </dd> + {{/繁體字}} + <dt>Radikal (简体字)</dt> + <dd> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation" no-animate="true"> + <span hanzi-data="{{text:简体字}}" hanzi-prop="radical"></span> + </div> + </dd> + {{#繁體字}} + <dt>Radikal (繁體字)</dt> + <dd> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical" class="hanzi-print"></span> + <div class="strichfolge-animation is-traditional" no-animate="true"> + <span hanzi-data="{{text:繁體字}}" hanzi-kind="traditional" hanzi-prop="radical"></span> + </div> + </dd> + {{/繁體字}} + </details> + </dl> + + <include src="src/components/notice/notice.html"></include> +</div> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/back' +</script> \ No newline at end of file diff --git a/src/templates/molaoshi/write/front.html b/src/templates/molaoshi/write/front.html new file mode 100644 index 0000000000000000000000000000000000000000..ed82b423a4db16d8ea4255cba9428a23ddca0da7 --- /dev/null +++ b/src/templates/molaoshi/write/front.html @@ -0,0 +1,34 @@ +{{#Deutsch}}{{#Schreiben anlegen}} +<style> + @import url(../../../components/global.css); +</style> + +<div class="exercise front anki-template-hanyu-write-front"> + <header class="card-info"> + <aside class="exercise-category"> + {{Subdeck}} + </aside> + <aside class="exercise-kind"> + {{Card}} + </aside> + </header> + </header> + + <dl class="prompt translations"> + <dt>Deutsch</dt> + <dd>{{Deutsch}}</dd> + <dt>Bemerkungen</dt> + <dd>{{Bemerkungen (Vorderseite)}}</dd> + </dl> +</div> + +<!-- Suppress default speech output and do that from script instead --> +<tts style="display: none" service="android" voice="zh_CN"></tts> + +<script type="module"> + import '../../../components/debug' +</script> +<script type="module"> + import '../../../components/front' +</script> +{{/Schreiben anlegen}}{{/Deutsch}} \ No newline at end of file diff --git a/test/build/fixtures/anki/.apkg-spec.yaml b/test/build/fixtures/anki/.apkg-spec.yaml deleted file mode 100644 index 92ef7488e7e8155afcb935ef23c3473690740a23..0000000000000000000000000000000000000000 --- a/test/build/fixtures/anki/.apkg-spec.yaml +++ /dev/null @@ -1,8 +0,0 @@ -content_version: 0.0.1 - -templates: -- q_a - -content: -- import_apkg: - note_type: Q/A Testnotetype \ No newline at end of file diff --git a/test/build/fixtures/anki/Test.apkg b/test/build/fixtures/anki/Test.apkg deleted file mode 100644 index 28a3614f2b228aa8ae1ba806c9914101a758cdcd..0000000000000000000000000000000000000000 Binary files a/test/build/fixtures/anki/Test.apkg and /dev/null differ diff --git a/test/build/fixtures/csv/.apkg-spec.yaml b/test/build/fixtures/csv/.apkg-spec.yaml deleted file mode 100644 index 274a5ede4ea93c1613898b87eac36aba91f2cb35..0000000000000000000000000000000000000000 --- a/test/build/fixtures/csv/.apkg-spec.yaml +++ /dev/null @@ -1,18 +0,0 @@ -content_version: 1.0.0 - -templates: -- q_a - -content: -- import_csv: - content_version: 2024-01-19 19:00:00+00:00 - note_type: Q/A Testnotetype - file_patterns: - - '*.csv' - # and to making one deck per card type - deck_name_pattern: '{{card_type}}' - fields_mapping: - - guid - - Question - - Answer - tags: [] \ No newline at end of file diff --git a/test/build/fixtures/csv/content.csv b/test/build/fixtures/csv/content.csv deleted file mode 100644 index 3c98112adacf4a22058eda6fb0e3b4646fe61b1f..0000000000000000000000000000000000000000 --- a/test/build/fixtures/csv/content.csv +++ /dev/null @@ -1 +0,0 @@ -test-csv-note-1;What is the scientific name of the only tapir living in Asia?;Tapirus indicus \ No newline at end of file diff --git a/test/build/fixtures/csv_updated_content/.apkg-spec.yaml b/test/build/fixtures/csv_updated_content/.apkg-spec.yaml deleted file mode 100644 index c20f61a2701c946e588aed80a1a36349bb9fd78e..0000000000000000000000000000000000000000 --- a/test/build/fixtures/csv_updated_content/.apkg-spec.yaml +++ /dev/null @@ -1,18 +0,0 @@ -content_version: 1.0.0 - -templates: -- q_a - -content: -- import_csv: - content_version: 2024-01-19 20:00:00+00:00 - note_type: Q/A Testnotetype - file_patterns: - - '*.csv' - # and to making one deck per card type - deck_name_pattern: '{{card_type}}' - fields_mapping: - - guid - - Question - - Answer - tags: [] \ No newline at end of file diff --git a/test/build/fixtures/csv_updated_content/content.csv b/test/build/fixtures/csv_updated_content/content.csv deleted file mode 100644 index d1f926732965ce42331922094e9d0e09843759b8..0000000000000000000000000000000000000000 --- a/test/build/fixtures/csv_updated_content/content.csv +++ /dev/null @@ -1 +0,0 @@ -test-csv-note-1;What is the scientific name of the only tapir living in Asia?;Tapirus indicus, Acrocodia indica being an outdated synonym. \ No newline at end of file diff --git a/test/build/fixtures/templates_updated/q_a/.template-spec.yaml b/test/build/fixtures/templates_updated/q_a/.template-spec.yaml deleted file mode 100644 index 02ef56a8c9e806366f130c7bf6b46a211305aa4d..0000000000000000000000000000000000000000 --- a/test/build/fixtures/templates_updated/q_a/.template-spec.yaml +++ /dev/null @@ -1,14 +0,0 @@ -template_version: 2024-01-20 19:00:00+00:00 - -note_type: - id: 2024-01-20 01:00:00+00:00 - name: Q/A Testnotetype - fields: - - Question - - Answer - -card_types: -- name: Q/A Testcardtype - template: q_a - -resource_paths: [] diff --git a/test/build/fixtures/templates_updated/q_a/q_a/back.html b/test/build/fixtures/templates_updated/q_a/q_a/back.html deleted file mode 100644 index 5cc04047c87ec3899621a9dd2ef1783bc121cee6..0000000000000000000000000000000000000000 --- a/test/build/fixtures/templates_updated/q_a/q_a/back.html +++ /dev/null @@ -1 +0,0 @@ -Back: {{Answer}} \ No newline at end of file diff --git a/test/build/fixtures/templates_updated/q_a/q_a/front.html b/test/build/fixtures/templates_updated/q_a/q_a/front.html deleted file mode 100644 index 51c00f17bd74b3f03674daf131ee9919167ac2fb..0000000000000000000000000000000000000000 --- a/test/build/fixtures/templates_updated/q_a/q_a/front.html +++ /dev/null @@ -1 +0,0 @@ -Front: {{Question}} \ No newline at end of file diff --git a/test/build/test_export_apkgs.py b/test/build/test_export_apkgs.py deleted file mode 100644 index 22b46f425ff7b1a204bae4922bef7f7ec1a88a4c..0000000000000000000000000000000000000000 --- a/test/build/test_export_apkgs.py +++ /dev/null @@ -1,337 +0,0 @@ -from anki.collection import Collection, ImportAnkiPackageRequest, ImportAnkiPackageOptions -from anki.import_export_pb2 import ImportAnkiPackageUpdateCondition -from build.export_apkgs import export_package_from_spec -from dataclasses import dataclass -from pathlib import Path -from tempfile import TemporaryDirectory -import unittest - -@dataclass -class MockArgs: - content: str - templates_dir: str - output_dir: str - dry_run: bool - -CONTENT_PATH_ANKI = 'test/build/fixtures/anki' -CONTENT_PATH_CSV = 'test/build/fixtures/csv' -CONTENT_PATH_CSV_UPDATED_CONTENT = 'test/build/fixtures/csv_updated_content' -TEMPLATES_PATH = 'test/build/fixtures/templates' -TEMPLATES_PATH_UPDATED = 'test/build/fixtures/templates_updated' - -class TestExportApkgs(unittest.TestCase): - def test_generate_once_and_reimport(self): - """ - Basic sanity check: if the exported package is imported twice, - everything is a duplicate and nothing should change. - """ - with TemporaryDirectory() as temp_collection_dir: - col = Collection(str(Path(temp_collection_dir) / "test.anki2")) - with TemporaryDirectory() as first_export_dir: - args_first = MockArgs( - content=CONTENT_PATH_CSV, - templates_dir=TEMPLATES_PATH, - output_dir=first_export_dir, - dry_run=False) - package = export_package_from_spec( - Path(CONTENT_PATH_CSV) / '.apkg-spec.yaml', - args_first) - - # import the first time, everything is new - result1 = col.import_anki_package(ImportAnkiPackageRequest( - package_path=str(package), - options=ImportAnkiPackageOptions( - merge_notetypes=True, - update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - with_scheduling=False, - with_deck_configs=False, - ) - )) - self.assertEqual(len(result1.log.new), 1) - self.assertEqual(len(result1.log.duplicate), 0) - - # now import again, nothing should change - result2 = col.import_anki_package(ImportAnkiPackageRequest( - package_path=str(package), - options=ImportAnkiPackageOptions( - merge_notetypes=True, - update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - with_scheduling=False, - with_deck_configs=False, - ) - )) - self.assertEqual(len(result2.log.duplicate) == 1 and len(result2.log.new), 0, - f'Expected the note to be recognized as duplicate.\nLog1:\n{result1.log}\nLog2:\n{result2.log}') - - def test_generate_twice_and_reimport(self): - """ - This checks that if we generate the package twice and import it twice, - then the second import will not change anything because the content is - supposed to be the same. - - If we introduce errors that lead to different note and card IDs being - generated, then this test will fail. - """ - with TemporaryDirectory() as temp_collection_dir: - col = Collection(str(Path(temp_collection_dir) / "test.anki2")) - with TemporaryDirectory() as first_export_dir: - args_first = MockArgs( - content=CONTENT_PATH_CSV, - templates_dir=TEMPLATES_PATH, - output_dir=first_export_dir, - dry_run=False) - with TemporaryDirectory() as second_export_dir: - args_second = MockArgs( - content=CONTENT_PATH_CSV, - templates_dir=TEMPLATES_PATH, - output_dir=second_export_dir, - dry_run=False) - spec_path = Path(CONTENT_PATH_CSV) / '.apkg-spec.yaml' - first_package = export_package_from_spec(spec_path, args_first) - second_package = export_package_from_spec(spec_path, args_second) - - # debug: uncomment to view for testing - # shutil.copy(first_package, './test-export-first.apkg.zip') - # shutil.copy(second_package, './test-export-second.apkg.zip') - - # import the first time, everything is new - result1 = col.import_anki_package(ImportAnkiPackageRequest( - package_path=str(first_package), - options=ImportAnkiPackageOptions( - merge_notetypes=True, - update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - with_scheduling=False, - with_deck_configs=False, - ) - )) - self.assertEqual(len(result1.log.new), 1) - self.assertEqual(len(result1.log.duplicate), 0) - - # now import again, nothing should change - result2 = col.import_anki_package(ImportAnkiPackageRequest( - package_path=str(second_package), - options=ImportAnkiPackageOptions( - merge_notetypes=True, - update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - with_scheduling=False, - with_deck_configs=False, - ) - )) - self.assertTrue( - len(result2.log.duplicate) == 1 and len(result2.log.new) == 0, - f'Expected second import to be a duplicate, but something else happened\nfirst log: {result1.log}\nsecond log:\n{result2.log}') - - def test_content_update_overwrites_previous_note(self): - """ - Tests that bumping the modification time will update notes from previous versions. - """ - with TemporaryDirectory() as temp_collection_dir: - col = Collection(str(Path(temp_collection_dir) / "test.anki2")) - with TemporaryDirectory() as first_export_dir: - args_first = MockArgs( - content=CONTENT_PATH_CSV, - templates_dir=TEMPLATES_PATH, - output_dir=first_export_dir, - dry_run=False) - with TemporaryDirectory() as second_export_dir: - args_second = MockArgs( - content=CONTENT_PATH_CSV_UPDATED_CONTENT, - templates_dir=TEMPLATES_PATH, - output_dir=second_export_dir, - dry_run=False) - spec_path_old = Path(f'{CONTENT_PATH_CSV}/.apkg-spec.yaml') - spec_path_new = Path(f'{CONTENT_PATH_CSV_UPDATED_CONTENT}/.apkg-spec.yaml') - first_package = export_package_from_spec(spec_path_old, args_first) - second_package = export_package_from_spec(spec_path_new, args_second) - - # import the old version version - result1 = col.import_anki_package(ImportAnkiPackageRequest( - package_path=str(first_package), - options=ImportAnkiPackageOptions( - merge_notetypes=True, - update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - with_scheduling=False, - with_deck_configs=False, - ) - )) - self.assertEqual(len(result1.log.updated), 0) - self.assertEqual(len(result1.log.new), 1) - self.assertEqual(len(result1.log.duplicate), 0) - - # now the update - result2 = col.import_anki_package(ImportAnkiPackageRequest( - package_path=str(second_package), - options=ImportAnkiPackageOptions( - merge_notetypes=True, - update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - with_scheduling=False, - with_deck_configs=False, - ) - )) - self.assertTrue(len(result2.log.updated) == 1 and len(result2.log.new) == 0 and len(result2.log.duplicate) == 0, - f'Expected the note to be recognized as update.\nLog1:\n{result1.log}\nLog2:\n{result2.log}') - - - def test_template_update_overwrites_previous_template_csv(self): - """ - Tests that bumping the modification time will update notes from previous versions - of CSV content. - """ - with TemporaryDirectory() as temp_collection_dir: - col = Collection(str(Path(temp_collection_dir) / "test.anki2")) - with TemporaryDirectory() as first_export_dir: - args_first = MockArgs( - content=CONTENT_PATH_CSV, - templates_dir=TEMPLATES_PATH, - output_dir=first_export_dir, - dry_run=False) - with TemporaryDirectory() as second_export_dir: - args_second = MockArgs( - content=CONTENT_PATH_CSV, - templates_dir=TEMPLATES_PATH_UPDATED, - output_dir=second_export_dir, - dry_run=False) - spec_path = Path(f'{CONTENT_PATH_CSV}/.apkg-spec.yaml') - first_package = export_package_from_spec(spec_path, args_first) - second_package = export_package_from_spec(spec_path, args_second) - - # debug: uncomment to view for testing - #shutil.copy(first_package, './test-export-first.apkg.zip') - #shutil.copy(second_package, './test-export-second.apkg.zip') - - # import the old version version - col.import_anki_package(ImportAnkiPackageRequest( - package_path=str(first_package), - options=ImportAnkiPackageOptions( - merge_notetypes=True, - update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - with_scheduling=False, - with_deck_configs=False, - ) - )) - - template = find_template(col, 'Q/A Testnotetype') - self.assertIsNotNone(template, 'template not found in collection') - self.assertEqual( - template['qfmt'], - '{{Question}}') - self.assertEqual( - template['afmt'], - '{{Answer}}') - - # now the update - result = col.import_anki_package(ImportAnkiPackageRequest( - package_path=str(second_package), - options=ImportAnkiPackageOptions( - merge_notetypes=True, - update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - with_scheduling=False, - with_deck_configs=False, - ) - )) - - # for some reason the change is only visible if we reload the collection - col.close() - col = Collection(str(Path(temp_collection_dir) / "test.anki2")) - - template = find_template(col, 'Q/A Testnotetype') - self.assertIsNotNone(template, 'template not found in collection') - self.assertEqual( - template['qfmt'], - 'Front: {{Question}}', - f'Template not updated successfully, log:\n{result.log}') - self.assertEqual( - template['afmt'], - 'Back: {{Answer}}') - - def test_template_update_overwrites_previous_template_anki(self): - """ - Tests that bumping the modification time will update notes from previous versions - of an imported anki package. - """ - with TemporaryDirectory() as temp_collection_dir: - col = Collection(str(Path(temp_collection_dir) / "test.anki2")) - with TemporaryDirectory() as first_export_dir: - args_first = MockArgs( - content=CONTENT_PATH_ANKI, - templates_dir=TEMPLATES_PATH, - output_dir=first_export_dir, - dry_run=False) - with TemporaryDirectory() as second_export_dir: - args_second = MockArgs( - content=CONTENT_PATH_ANKI, - templates_dir=TEMPLATES_PATH_UPDATED, - output_dir=second_export_dir, - dry_run=False) - spec_path = Path(f'{CONTENT_PATH_ANKI}/.apkg-spec.yaml') - first_package = export_package_from_spec(spec_path, args_first) - second_package = export_package_from_spec(spec_path, args_second) - - # debug: uncomment to view for testing - #shutil.copy(first_package, './test-export-first.apkg.zip') - #shutil.copy(second_package, './test-export-second.apkg.zip') - - # import the old version version - col.import_anki_package(ImportAnkiPackageRequest( - package_path=str(first_package), - options=ImportAnkiPackageOptions( - merge_notetypes=True, - update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - with_scheduling=False, - with_deck_configs=False, - ) - )) - - template = find_template(col, 'Q/A Testnotetype') - self.assertIsNotNone(template, 'template not found in collection') - self.assertEqual( - template['qfmt'], - '{{Question}}') - self.assertEqual( - template['afmt'], - '{{Answer}}') - - # now the update - result = col.import_anki_package(ImportAnkiPackageRequest( - package_path=str(second_package), - options=ImportAnkiPackageOptions( - merge_notetypes=True, - update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER, - with_scheduling=False, - with_deck_configs=False, - ) - )) - - # for some reason the change is only visible if we reload the collection - col.close() - col = Collection(str(Path(temp_collection_dir) / "test.anki2")) - - template = find_template(col, 'Q/A Testnotetype') - self.assertIsNotNone(template, 'template not found in collection') - self.assertEqual( - template['qfmt'], - 'Front: {{Question}}', - f'Template not updated successfully, log:\n{result.log}') - self.assertEqual( - template['afmt'], - 'Back: {{Answer}}') - -def find_template(col: Collection, name: str): - template = None - for name_and_id in col.models.all_names_and_ids(): - if name_and_id.name == name: - if template is None: - template = col.models.get(name_and_id.id)['tmpls'][0] - else: - raise Exception(f'Found more than one template with name {name}') - return template \ No newline at end of file diff --git a/test/templates/hanzi-data.test.ts b/test/templates/hanzi-data.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..cadfc82bfdbe31f3ff20276d95974de6499c6127 --- /dev/null +++ b/test/templates/hanzi-data.test.ts @@ -0,0 +1,202 @@ +import { StrokeType } from '../../src-common/stroke-encodings' +import { + GetHanziDataKind, + getHanziData +} from '../../src/components/hanzi-data' + +describe('stroke counts', () => { + describe('default kind', () => { + const kind = GetHanziDataKind.DEFAULT + const testCases = [ + { character: '错', expectedCount: '5+8' }, + { character: '你', expectedCount: '2+5' }, + { character: '笔', expectedCount: '6+4' } + ] + for (const testCase of testCases) { + test(`stroke count of ${testCase.character}`, async () => { + const data = await getHanziData({ + char: testCase.character, + kind + }) + const actualCount = data?.count + expect(actualCount).toBe(testCase.expectedCount) + }) + } + }) + describe('traditional kind', () => { + const kind = GetHanziDataKind.TRADITIONAL + const testCases = [ + { character: '紫', expectedCount: '6+6' }, + { character: '幫', expectedCount: '3+14' }, + { character: '處', expectedCount: '6+5' }, + { character: '夏', expectedCount: '3+7' }, + { character: '鄰', expectedCount: '7+12' }, + { character: '圜', expectedCount: '3+13' }, + { character: '璮', expectedCount: '5+13' }, + { character: '刷', expectedCount: '2+6' }, + { character: '戀', expectedCount: '4+19' }, + { character: '矮', expectedCount: '5+8' }, + { character: '驚', expectedCount: '10+13' }, + { character: '雞', expectedCount: '8+10' }, + { character: '顱', expectedCount: '9+16' }, + { character: '襪', expectedCount: '6+15' }, + { character: '勵', expectedCount: '2+15' }, + { character: '藝', expectedCount: '6+15' }, + { character: '歡', expectedCount: '4+18' }, + { character: '戰', expectedCount: '4+12' }, + { character: '翻', expectedCount: '6+12' }, + { character: '敵', expectedCount: '4+11' }, + { character: '彎', expectedCount: '3+19' }, + { character: '籍', expectedCount: '6+14' }, + { character: '餓', expectedCount: '9+7' }, + { character: '隨', expectedCount: '8+13' }, + { character: '翼', expectedCount: '6+11' }, + { character: '響', expectedCount: '9+11' }, + { character: '矊', expectedCount: '5+14' }, + { character: '聲', expectedCount: '6+11' }, + { character: '磬', expectedCount: '5+11' }, + { character: '獸', expectedCount: '4+15' }, + { character: '義', expectedCount: '6+7' }, + { character: '登', expectedCount: '5+7' }, + { character: '灣', expectedCount: '4+22' }, + { character: '驢', expectedCount: '10+16' }, + { character: '壓', expectedCount: '3+14' }, + { character: '避', expectedCount: '7+13' }, + { character: '甩', expectedCount: '5+0' }, + { character: '懈', expectedCount: '4+13' }, + { character: '靈', expectedCount: '8+16' }, + { character: '攤', expectedCount: '4+19' }, + { character: '氧', expectedCount: '4+6' }, + { character: '參', expectedCount: '2+9' }, + { character: '熱', expectedCount: '4+11' }, + { character: '餐', expectedCount: '9+7' }, + { character: '虝', expectedCount: '6+6' }, + { character: '聽', expectedCount: '6+16' } + ] + for (const testCase of testCases) { + test(`stroke count of ${testCase.character}`, async () => { + const data = await getHanziData({ + char: testCase.character, + kind + }) + const actualCount = data?.count + expect(actualCount).toBe(testCase.expectedCount) + }) + } + }) +}) + +describe('stroke types', () => { + const testCases = [ + { + hanzi: '艸', + expected: [ + StrokeType.SHUZHE, + StrokeType.SHU, + StrokeType.PIE, + StrokeType.SHUZHE, + StrokeType.SHU, + StrokeType.SHU + ] + } + ] + for (const { hanzi, expected } of testCases) { + test(hanzi, async () => { + const { strokeTypes } = await getHanziData({ char: hanzi }) + expect(strokeTypes).toEqual(expected) + }) + } +}) + +describe('radicals', () => { + describe('default kind', () => { + const kind = GetHanziDataKind.DEFAULT + const testCases = [ + ['王', '王'], + ['了', '乙'], + ['草', '艹'], + ['笔', '竹'] + ] + for (const [hanzi, expectedRadical] of testCases) { + test(hanzi, async () => { + const data = await getHanziData({ char: hanzi, kind }) + const radical = data?.radical + expect(radical).toBe(expectedRadical) + }) + } + }) + describe('omitted kind', () => { + test('了', async () => { + // no kind also means default + const data = await getHanziData({ char: '了' }) + const radical = data?.radical + expect(radical).toBe('乙') + }) + }) + describe('traditional kind', () => { + const kind = GetHanziDataKind.TRADITIONAL + const testCases = [ + ['王', '玉'], + ['了', '亅'], + ['蘭', '艸'], + ['聽', '耳'], + ['笔', '竹'], + ['齣', '齒'] + ] + for (const [hanzi, expectedRadical] of testCases) { + test(hanzi, async () => { + const data = await getHanziData({ char: hanzi, kind }) + const radical = data?.radical + expect(radical).toBe(expectedRadical) + }) + } + }) +}) + +describe('SVG data', () => { + const mustHave = [ + '凵', + '季', + '木', + '纔', + '裏', + '這', + '阝', + '餵', + '鼕', + '齒' + ] + for (const hanzi of mustHave) { + test(hanzi, async () => { + const data = await getHanziData({ char: hanzi }) + expect(data?.strokes?.length).toBeGreaterThan(0) + }) + } +}) + +describe('SVG data for grass radicals default vs. traditional', () => { + const grassChars = [ + '若', + '草', + '花', + '苦', + '莫', + '苗' + ] + for (const grassChar of grassChars) { + test(grassChar, async () => { + const defaultData = await getHanziData({ char: grassChar }) + const tradData = await getHanziData({ + char: grassChar, + kind: GetHanziDataKind.TRADITIONAL + }) + expect(tradData.strokes.length).toBe(defaultData.strokes.length + 1) + expect(tradData.strokeTypes.slice(0, 4)).toEqual([ + StrokeType.SHU, + StrokeType.HENG, + StrokeType.SHU, + StrokeType.HENG + ]) + }) + } +}) diff --git a/test/templates/is-hanzi.test.ts b/test/templates/is-hanzi.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..78338eda57d9d3ed1cba9468a8e5278f01ccb412 --- /dev/null +++ b/test/templates/is-hanzi.test.ts @@ -0,0 +1,29 @@ +import { isMaybeHanzi } from '../../src/components/is-hanzi' + +describe('accepts Hanzi', () => { + const samples = [ + '⽱', + '⻊', + '貘', + '貘⻊⽱' + ] + for (const sample of samples) { + test(sample, () => { + expect(isMaybeHanzi(sample)).toBe(true) + }) + } +}) + +describe('rejects Latin characters, umlauts and punctuation', () => { + const samples = [ + '', // empty string is also not hanzi + 'asdfÄÜ?…', + '…', + '-–—' + ] + for (const sample of samples) { + test(sample, () => { + expect(isMaybeHanzi(sample)).toBe(false) + }) + } +}) diff --git a/test/templates/lut.test.ts b/test/templates/lut.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..894b4bad90955d541cfc6380ed8e59168381030b --- /dev/null +++ b/test/templates/lut.test.ts @@ -0,0 +1,41 @@ +import { getHanziData } from '../../src/components/hanzi-data' +import { lookup } from '../../src/components/hanzi-data/lut' + +describe('table properties', () => { + const testCases = [ + { hanzi: '草', prop: 'radicalMeaningDe', expected: 'Gras' }, + { hanzi: '母', prop: 'radicalMeaningDe', expected: 'Mutter' }, + { + hanzi: '木', + prop: 'strokeTypeNumbers', + expected: ['①', '②', '③', '④'] + }, + { + hanzi: '道', + prop: 'strokeTypeNumbers', + expected: [ + '④', + '③', + '①', + '③', + '②', + '⑤', + '①', + '①', + '①', + '④', + '⑤', + '④' + ] + } + ] + for (const { hanzi, prop, expected } of testCases) { + test(`${prop} of ${hanzi}`, async () => { + const actual = lookup( + await getHanziData({ char: hanzi }), + prop + ) + expect(actual).toEqual(expected) + }) + } +})