From 5a2bc4e542b7f22d1e6a4ba318cfcdc33817d34a Mon Sep 17 00:00:00 2001 From: Kuuuube <61125188+Kuuuube@users.noreply.github.com> Date: Fri, 2 Feb 2024 21:53:42 -0500 Subject: Add frequency number handlebars (#600) * Add frequencies-num handlebar * Fix handlebar name * Fix inconsistent variable name format * Add frequency-number to anki tests * Use full names for total and frequency variables * Migrate handlebars to JS, split rank and occurance, add average * Remove left behind frequency-number * Fix "occurrence" spelling * Cleanup types * Add frequency support for kanji cards * Fix code style * Clean up most of duplicate code and merge functions * Fix frequencies.length check * Use less witchcraft and remove redundant type casting --- .../default-anki-field-templates.handlebars | 32 ++++++++++ ext/js/data/sandbox/anki-note-data-creator.js | 69 ++++++++++++++++++++++ ext/js/pages/settings/anki-controller.js | 9 +++ 3 files changed, 110 insertions(+) (limited to 'ext') diff --git a/ext/data/templates/default-anki-field-templates.handlebars b/ext/data/templates/default-anki-field-templates.handlebars index 0ea98e5e..07efd07e 100644 --- a/ext/data/templates/default-anki-field-templates.handlebars +++ b/ext/data/templates/default-anki-field-templates.handlebars @@ -302,6 +302,38 @@ {{~/if~}} {{/inline}} +{{#*inline "frequency-harmonic-rank"}} + {{~#if (op "===" definition.frequencyHarmonic -1) ~}} + 9999999 + {{~else ~}} + {{definition.frequencyHarmonic}} + {{~/if~}} +{{/inline}} + +{{#*inline "frequency-harmonic-occurrence"}} + {{~#if (op "===" definition.frequencyHarmonic -1) ~}} + 0 + {{~else ~}} + {{definition.frequencyHarmonic}} + {{~/if~}} +{{/inline}} + +{{#*inline "frequency-average-rank"}} + {{~#if (op "===" definition.frequencyAverage -1) ~}} + 9999999 + {{~else ~}} + {{definition.frequencyAverage}} + {{~/if~}} +{{/inline}} + +{{#*inline "frequency-average-occurrence"}} + {{~#if (op "===" definition.frequencyAverage -1) ~}} + 0 + {{~else ~}} + {{definition.frequencyAverage}} + {{~/if~}} +{{/inline}} + {{#*inline "stroke-count"}} {{~#scope~}} {{~set "found" false~}} diff --git a/ext/js/data/sandbox/anki-note-data-creator.js b/ext/js/data/sandbox/anki-note-data-creator.js index 51679662..79570532 100644 --- a/ext/js/data/sandbox/anki-note-data-creator.js +++ b/ext/js/data/sandbox/anki-note-data-creator.js @@ -170,6 +170,67 @@ function getPublicContext(context) { }; } +/** + * @param {import('dictionary').TermDictionaryEntry|import('dictionary').KanjiDictionaryEntry} dictionaryEntry + * @returns {number[]} + */ +function getFrequencyNumbers(dictionaryEntry) { + let previousDictionary; + const frequencies = []; + for (const {dictionary, frequency, displayValue} of dictionaryEntry.frequencies) { + if (dictionary === previousDictionary) { + continue; + } + previousDictionary = dictionary; + + if (displayValue !== null) { + const frequencyMatch = displayValue.match(/\d+/); + if (frequencyMatch !== null) { + frequencies.push(Number.parseInt(frequencyMatch[0], 10)); + continue; + } + } + frequencies.push(frequency); + } + return frequencies; +} + +/** + * @param {import('dictionary').TermDictionaryEntry|import('dictionary').KanjiDictionaryEntry} dictionaryEntry + * @returns {number} + */ +function getFrequencyHarmonic(dictionaryEntry) { + const frequencies = getFrequencyNumbers(dictionaryEntry); + + if (frequencies.length === 0) { + return -1; + } + + let total = 0; + for (const frequency of frequencies) { + total += 1 / frequency; + } + return Math.floor(frequencies.length / total); +} + +/** + * @param {import('dictionary').TermDictionaryEntry|import('dictionary').KanjiDictionaryEntry} dictionaryEntry + * @returns {number} + */ +function getFrequencyAverage(dictionaryEntry) { + const frequencies = getFrequencyNumbers(dictionaryEntry); + + if (frequencies.length === 0) { + return -1; + } + + let total = 0; + for (const frequency of frequencies) { + total += frequency; + } + return Math.floor(total / frequencies.length); +} + /** * @param {import('dictionary').DictionaryEntry} dictionaryEntry * @returns {import('anki-templates').PitchGroup[]} @@ -272,6 +333,8 @@ function getKanjiDefinition(dictionaryEntry, context) { const stats = createCachedValue(getKanjiStats.bind(null, dictionaryEntry)); const tags = createCachedValue(convertTags.bind(null, dictionaryEntry.tags)); const frequencies = createCachedValue(getKanjiFrequencies.bind(null, dictionaryEntry)); + const frequencyHarmonic = createCachedValue(getFrequencyHarmonic.bind(null, dictionaryEntry)); + const frequencyAverage = createCachedValue(getFrequencyAverage.bind(null, dictionaryEntry)); const cloze = createCachedValue(getCloze.bind(null, dictionaryEntry, context)); return { @@ -284,6 +347,8 @@ function getKanjiDefinition(dictionaryEntry, context) { get tags() { return getCachedValue(tags); }, get stats() { return getCachedValue(stats); }, get frequencies() { return getCachedValue(frequencies); }, + get frequencyHarmonic() { return getCachedValue(frequencyHarmonic); }, + get frequencyAverage() { return getCachedValue(frequencyAverage); }, url, get cloze() { return getCachedValue(cloze); } }; @@ -366,6 +431,8 @@ function getTermDefinition(dictionaryEntry, context, resultOutputMode) { const termTags = createCachedValue(getTermTags.bind(null, dictionaryEntry, type)); const expressions = createCachedValue(getTermExpressions.bind(null, dictionaryEntry)); const frequencies = createCachedValue(getTermFrequencies.bind(null, dictionaryEntry)); + const frequencyHarmonic = createCachedValue(getFrequencyHarmonic.bind(null, dictionaryEntry)); + const frequencyAverage = createCachedValue(getFrequencyAverage.bind(null, dictionaryEntry)); const pitches = createCachedValue(getTermPitches.bind(null, dictionaryEntry)); const phoneticTranscriptions = createCachedValue(getTermPhoneticTranscriptions.bind(null, dictionaryEntry)); const glossary = createCachedValue(getTermGlossaryArray.bind(null, dictionaryEntry, type)); @@ -403,6 +470,8 @@ function getTermDefinition(dictionaryEntry, context, resultOutputMode) { get termTags() { return getCachedValue(termTags); }, get definitions() { return getCachedValue(commonInfo).definitions; }, get frequencies() { return getCachedValue(frequencies); }, + get frequencyHarmonic() { return getCachedValue(frequencyHarmonic); }, + get frequencyAverage() { return getCachedValue(frequencyAverage); }, get pitches() { return getCachedValue(pitches); }, get phoneticTranscriptions() { return getCachedValue(phoneticTranscriptions); }, sourceTermExactMatchCount, diff --git a/ext/js/pages/settings/anki-controller.js b/ext/js/pages/settings/anki-controller.js index ae6a71db..a0d57457 100644 --- a/ext/js/pages/settings/anki-controller.js +++ b/ext/js/pages/settings/anki-controller.js @@ -138,6 +138,10 @@ export class AnkiController { 'document-title', 'expression', 'frequencies', + 'frequency-harmonic-rank', + 'frequency-harmonic-occurrence', + 'frequency-average-rank', + 'frequency-average-occurrence', 'furigana', 'furigana-plain', 'glossary', @@ -168,6 +172,11 @@ export class AnkiController { 'cloze-suffix', 'dictionary', 'document-title', + 'frequencies', + 'frequency-harmonic-rank', + 'frequency-harmonic-occurrence', + 'frequency-average-rank', + 'frequency-average-occurrence', 'glossary', 'kunyomi', 'onyomi', -- cgit v1.2.3