diff options
Diffstat (limited to 'ext/js')
| -rw-r--r-- | ext/js/data/sandbox/anki-note-data-creator.js | 102 | ||||
| -rw-r--r-- | ext/js/dictionary/dictionary-data-util.js | 93 | ||||
| -rw-r--r-- | ext/js/dictionary/dictionary-database.js | 2 | ||||
| -rw-r--r-- | ext/js/display/display-generator.js | 64 | ||||
| -rw-r--r-- | ext/js/language/translator.js | 44 | ||||
| -rw-r--r-- | ext/js/pages/settings/anki-controller.js | 1 | ||||
| -rw-r--r-- | ext/js/templates/sandbox/anki-template-renderer.js | 5 | 
7 files changed, 258 insertions, 53 deletions
| diff --git a/ext/js/data/sandbox/anki-note-data-creator.js b/ext/js/data/sandbox/anki-note-data-creator.js index 9d93b497..c0a11869 100644 --- a/ext/js/data/sandbox/anki-note-data-creator.js +++ b/ext/js/data/sandbox/anki-note-data-creator.js @@ -55,6 +55,8 @@ export class AnkiNoteDataCreator {          const context2 = this.createCachedValue(this._getPublicContext.bind(this, context));          const pitches = this.createCachedValue(this._getPitches.bind(this, dictionaryEntry));          const pitchCount = this.createCachedValue(this._getPitchCount.bind(this, pitches)); +        const phoneticTranscriptions = this.createCachedValue(this._getPhoneticTranscriptions.bind(this, dictionaryEntry)); +          if (typeof media !== 'object' || media === null || Array.isArray(media)) {              media = {                  audio: void 0, @@ -82,6 +84,7 @@ export class AnkiNoteDataCreator {              get uniqueReadings() { return self.getCachedValue(uniqueReadings); },              get pitches() { return self.getCachedValue(pitches); },              get pitchCount() { return self.getCachedValue(pitchCount); }, +            get phoneticTranscriptions() { return self.getCachedValue(phoneticTranscriptions); },              get context() { return self.getCachedValue(context2); },              media,              dictionaryEntry @@ -193,7 +196,11 @@ export class AnkiNoteDataCreator {              for (const {dictionary, pronunciations} of DictionaryDataUtil.getGroupedPronunciations(dictionaryEntry)) {                  /** @type {import('anki-templates').Pitch[]} */                  const pitches = []; -                for (const {terms, reading, position, nasalPositions, devoicePositions, tags, exclusiveTerms, exclusiveReadings} of pronunciations) { +                for (const groupedPronunciation of pronunciations) { +                    const {pronunciation} = groupedPronunciation; +                    if (pronunciation.type !== 'pitch-accent') { continue; } +                    const {position, nasalPositions, devoicePositions, tags} = pronunciation; +                    const {terms, reading, exclusiveTerms, exclusiveReadings} = groupedPronunciation;                      pitches.push({                          expressions: terms,                          reading, @@ -212,6 +219,35 @@ export class AnkiNoteDataCreator {      }      /** +     * @param {import('dictionary').DictionaryEntry} dictionaryEntry +     * @returns {import('anki-templates').TranscriptionGroup[]} +     */ +    _getPhoneticTranscriptions(dictionaryEntry) { +        const results = []; +        if (dictionaryEntry.type === 'term') { +            for (const {dictionary, pronunciations} of DictionaryDataUtil.getGroupedPronunciations(dictionaryEntry)) { +                const phoneticTranscriptions = []; +                for (const groupedPronunciation of pronunciations) { +                    const {pronunciation} = groupedPronunciation; +                    if (pronunciation.type !== 'phonetic-transcription') { continue; } +                    const {ipa, tags} = pronunciation; +                    const {terms, reading, exclusiveTerms, exclusiveReadings} = groupedPronunciation; +                    phoneticTranscriptions.push({ +                        expressions: terms, +                        reading, +                        ipa, +                        tags, +                        exclusiveExpressions: exclusiveTerms, +                        exclusiveReadings +                    }); +                } +                results.push({dictionary, phoneticTranscriptions}); +            } +        } +        return results; +    } + +    /**       * @param {import('anki-templates-internal').CachedValue<import('anki-templates').PitchGroup[]>} cachedPitches       * @returns {number}       */ @@ -353,6 +389,7 @@ export class AnkiNoteDataCreator {          const expressions = this.createCachedValue(this._getTermExpressions.bind(this, dictionaryEntry));          const frequencies = this.createCachedValue(this._getTermFrequencies.bind(this, dictionaryEntry));          const pitches = this.createCachedValue(this._getTermPitches.bind(this, dictionaryEntry)); +        const phoneticTranscriptions = this.createCachedValue(this._getTermPhoneticTranscriptions.bind(this, dictionaryEntry));          const glossary = this.createCachedValue(this._getTermGlossaryArray.bind(this, dictionaryEntry, type));          const cloze = this.createCachedValue(this._getCloze.bind(this, dictionaryEntry, context));          const furiganaSegments = this.createCachedValue(this._getTermFuriganaSegments.bind(this, dictionaryEntry, type)); @@ -389,6 +426,7 @@ export class AnkiNoteDataCreator {              get definitions() { return self.getCachedValue(commonInfo).definitions; },              get frequencies() { return self.getCachedValue(frequencies); },              get pitches() { return self.getCachedValue(pitches); }, +            get phoneticTranscriptions() { return self.getCachedValue(phoneticTranscriptions); },              sourceTermExactMatchCount,              url,              get cloze() { return self.getCachedValue(cloze); }, @@ -485,15 +523,16 @@ export class AnkiNoteDataCreator {      /**       * @param {import('dictionary').TermDictionaryEntry} dictionaryEntry -     * @returns {import('anki-templates').TermPronunciation[]} +     * @returns {import('anki-templates').TermPitchAccent[]}       */      _getTermPitches(dictionaryEntry) {          // eslint-disable-next-line @typescript-eslint/no-this-alias          const self = this;          const results = [];          const {headwords} = dictionaryEntry; -        for (const {headwordIndex, dictionary, dictionaryIndex, dictionaryPriority, pitches} of dictionaryEntry.pronunciations) { +        for (const {headwordIndex, dictionary, dictionaryIndex, dictionaryPriority, pronunciations} of dictionaryEntry.pronunciations) {              const {term, reading} = headwords[headwordIndex]; +            const pitches = DictionaryDataUtil.getPronunciationsOfType(pronunciations, 'pitch-accent');              const cachedPitches = this.createCachedValue(this._getTermPitchesInner.bind(this, pitches));              results.push({                  index: results.length, @@ -512,8 +551,8 @@ export class AnkiNoteDataCreator {      }      /** -     * @param {import('dictionary').TermPitch[]} pitches -     * @returns {import('anki-templates').TermPitch[]} +     * @param {import('dictionary').PitchAccent[]} pitches +     * @returns {import('anki-templates').PitchAccent[]}       */      _getTermPitchesInner(pitches) {          // eslint-disable-next-line @typescript-eslint/no-this-alias @@ -531,6 +570,52 @@ export class AnkiNoteDataCreator {      /**       * @param {import('dictionary').TermDictionaryEntry} dictionaryEntry +     * @returns {import('anki-templates').TermPhoneticTranscription[]} +     */ +    _getTermPhoneticTranscriptions(dictionaryEntry) { +        const results = []; +        const {headwords} = dictionaryEntry; +        for (const {headwordIndex, dictionary, dictionaryIndex, dictionaryPriority, pronunciations} of dictionaryEntry.pronunciations) { +            const {term, reading} = headwords[headwordIndex]; +            const phoneticTranscriptions = DictionaryDataUtil.getPronunciationsOfType(pronunciations, 'phonetic-transcription'); +            const termPhoneticTranscriptions = this._getTermPhoneticTranscriptionsInner(phoneticTranscriptions); +            results.push({ +                index: results.length, +                expressionIndex: headwordIndex, +                dictionary, +                dictionaryOrder: { +                    index: dictionaryIndex, +                    priority: dictionaryPriority +                }, +                expression: term, +                reading, +                get phoneticTranscriptions() { return termPhoneticTranscriptions; } +            }); +        } + +        return results; +    } + +    /** +     * @param {import('dictionary').PhoneticTranscription[]} phoneticTranscriptions +     * @returns {import('anki-templates').PhoneticTranscription[]} +     */ +    _getTermPhoneticTranscriptionsInner(phoneticTranscriptions) { +        // eslint-disable-next-line @typescript-eslint/no-this-alias +        const self = this; +        const results = []; +        for (const {ipa, tags} of phoneticTranscriptions) { +            const cachedTags = this.createCachedValue(this._convertTags.bind(this, tags)); +            results.push({ +                ipa, +                get tags() { return self.getCachedValue(cachedTags); } +            }); +        } +        return results; +    } + +    /** +     * @param {import('dictionary').TermDictionaryEntry} dictionaryEntry       * @returns {import('anki-templates').TermHeadword[]}       */      _getTermExpressions(dictionaryEntry) { @@ -592,16 +677,17 @@ export class AnkiNoteDataCreator {      /**       * @param {import('dictionary').TermDictionaryEntry} dictionaryEntry       * @param {number} i -     * @returns {import('anki-templates').TermPronunciation[]} +     * @returns {import('anki-templates').TermPitchAccent[]}       */      _getTermExpressionPitches(dictionaryEntry, i) {          // eslint-disable-next-line @typescript-eslint/no-this-alias          const self = this;          const results = []; -        const {headwords, pronunciations} = dictionaryEntry; -        for (const {headwordIndex, dictionary, dictionaryIndex, dictionaryPriority, pitches} of pronunciations) { +        const {headwords, pronunciations: termPronunciations} = dictionaryEntry; +        for (const {headwordIndex, dictionary, dictionaryIndex, dictionaryPriority, pronunciations} of termPronunciations) {              if (headwordIndex !== i) { continue; }              const {term, reading} = headwords[headwordIndex]; +            const pitches = DictionaryDataUtil.getPronunciationsOfType(pronunciations, 'pitch-accent');              const cachedPitches = this.createCachedValue(this._getTermPitchesInner.bind(this, pitches));              results.push({                  index: results.length, diff --git a/ext/js/dictionary/dictionary-data-util.js b/ext/js/dictionary/dictionary-data-util.js index a54b043b..50ae4b11 100644 --- a/ext/js/dictionary/dictionary-data-util.js +++ b/ext/js/dictionary/dictionary-data-util.js @@ -135,7 +135,7 @@ export class DictionaryDataUtil {       * @returns {import('dictionary-data-util').DictionaryGroupedPronunciations[]}       */      static getGroupedPronunciations(dictionaryEntry) { -        const {headwords, pronunciations} = dictionaryEntry; +        const {headwords, pronunciations: termPronunciations} = dictionaryEntry;          const allTerms = new Set();          const allReadings = new Set(); @@ -146,23 +146,20 @@ export class DictionaryDataUtil {          /** @type {Map<string, import('dictionary-data-util').GroupedPronunciationInternal[]>} */          const groupedPronunciationsMap = new Map(); -        for (const {headwordIndex, dictionary, pitches} of pronunciations) { +        for (const {headwordIndex, dictionary, pronunciations} of termPronunciations) {              const {term, reading} = headwords[headwordIndex];              let dictionaryGroupedPronunciationList = groupedPronunciationsMap.get(dictionary);              if (typeof dictionaryGroupedPronunciationList === 'undefined') {                  dictionaryGroupedPronunciationList = [];                  groupedPronunciationsMap.set(dictionary, dictionaryGroupedPronunciationList);              } -            for (const {position, nasalPositions, devoicePositions, tags} of pitches) { -                let groupedPronunciation = this._findExistingGroupedPronunciation(reading, position, nasalPositions, devoicePositions, tags, dictionaryGroupedPronunciationList); +            for (const pronunciation of pronunciations) { +                let groupedPronunciation = this._findExistingGroupedPronunciation(reading, pronunciation, dictionaryGroupedPronunciationList);                  if (groupedPronunciation === null) {                      groupedPronunciation = { +                        pronunciation,                          terms: new Set(), -                        reading, -                        position, -                        nasalPositions, -                        devoicePositions, -                        tags +                        reading                      };                      dictionaryGroupedPronunciationList.push(groupedPronunciation);                  } @@ -177,29 +174,44 @@ export class DictionaryDataUtil {              /** @type {import('dictionary-data-util').GroupedPronunciation[]} */              const pronunciations2 = [];              for (const groupedPronunciation of dictionaryGroupedPronunciationList) { -                const {terms, reading, position, nasalPositions, devoicePositions, tags} = groupedPronunciation; +                const {pronunciation, terms, reading} = groupedPronunciation;                  const exclusiveTerms = !this._areSetsEqual(terms, allTerms) ? this._getSetIntersection(terms, allTerms) : [];                  const exclusiveReadings = [];                  if (multipleReadings) {                      exclusiveReadings.push(reading);                  }                  pronunciations2.push({ +                    pronunciation,                      terms: [...terms],                      reading, -                    position, -                    nasalPositions, -                    devoicePositions, -                    tags,                      exclusiveTerms,                      exclusiveReadings                  });              } +              results2.push({dictionary, pronunciations: pronunciations2});          }          return results2;      }      /** +     * @template {import('dictionary').PronunciationType} T +     * @param {import('dictionary').Pronunciation[]} pronunciations +     * @param {T} type +     * @returns {import('dictionary').PronunciationGeneric<T>[]} +     */ +    static getPronunciationsOfType(pronunciations, type) { +        /** @type {import('dictionary').PronunciationGeneric<T>[]} */ +        const results = []; +        for (const pronunciation of pronunciations) { +            if (pronunciation.type !== type) { continue; } +            // This is type safe, but for some reason the cast is needed. +            results.push(/** @type {import('dictionary').PronunciationGeneric<T>} */ (pronunciation)); +        } +        return results; +    } + +    /**       * @param {import('dictionary').Tag[]|import('anki-templates').Tag[]} termTags       * @returns {import('dictionary-data-util').TermFrequencyType}       */ @@ -288,26 +300,49 @@ export class DictionaryDataUtil {      /**       * @param {string} reading -     * @param {number} position -     * @param {number[]} nasalPositions -     * @param {number[]} devoicePositions -     * @param {import('dictionary').Tag[]} tags +     * @param {import('dictionary').Pronunciation} pronunciation       * @param {import('dictionary-data-util').GroupedPronunciationInternal[]} groupedPronunciationList       * @returns {?import('dictionary-data-util').GroupedPronunciationInternal}       */ -    static _findExistingGroupedPronunciation(reading, position, nasalPositions, devoicePositions, tags, groupedPronunciationList) { -        for (const pitchInfo of groupedPronunciationList) { -            if ( -                pitchInfo.reading === reading && -                pitchInfo.position === position && -                this._areArraysEqual(pitchInfo.nasalPositions, nasalPositions) && -                this._areArraysEqual(pitchInfo.devoicePositions, devoicePositions) && -                this._areTagListsEqual(pitchInfo.tags, tags) -            ) { -                return pitchInfo; +    static _findExistingGroupedPronunciation(reading, pronunciation, groupedPronunciationList) { +        const existingGroupedPronunciation = groupedPronunciationList.find((groupedPronunciation) => { +            return groupedPronunciation.reading === reading && this._arePronunciationsEquivalent(groupedPronunciation, pronunciation); +        }); + +        return existingGroupedPronunciation || null; +    } + +    /** +     * @param {import('dictionary-data-util').GroupedPronunciationInternal} groupedPronunciation +     * @param {import('dictionary').Pronunciation} pronunciation2 +     * @returns {boolean} +     */ +    static _arePronunciationsEquivalent({pronunciation: pronunciation1}, pronunciation2) { +        if ( +            pronunciation1.type !== pronunciation2.type || +            !this._areTagListsEqual(pronunciation1.tags, pronunciation2.tags) +        ) { +            return false; +        } +        switch (pronunciation1.type) { +            case 'pitch-accent': +            { +                // This cast is valid based on the type check at the start of the function. +                const pitchAccent2 = /** @type {import('dictionary').PitchAccent} */ (pronunciation2); +                return ( +                    pronunciation1.position === pitchAccent2.position && +                    this._areArraysEqual(pronunciation1.nasalPositions, pitchAccent2.nasalPositions) && +                    this._areArraysEqual(pronunciation1.devoicePositions, pitchAccent2.devoicePositions) +                ); +            } +            case 'phonetic-transcription': +            { +                // This cast is valid based on the type check at the start of the function. +                const phoneticTranscription2 = /** @type {import('dictionary').PhoneticTranscription} */ (pronunciation2); +                return pronunciation1.ipa === phoneticTranscription2.ipa;              }          } -        return null; +        return true;      }      /** diff --git a/ext/js/dictionary/dictionary-database.js b/ext/js/dictionary/dictionary-database.js index 45c5c6fd..02db6322 100644 --- a/ext/js/dictionary/dictionary-database.js +++ b/ext/js/dictionary/dictionary-database.js @@ -627,6 +627,8 @@ export class DictionaryDatabase {                  return {index, term, mode, data, dictionary};              case 'pitch':                  return {index, term, mode, data, dictionary}; +            case 'ipa': +                return {index, term, mode, data, dictionary};              default:                  throw new Error(`Unknown mode: ${mode}`);          } diff --git a/ext/js/display/display-generator.js b/ext/js/display/display-generator.js index b91d0ce9..3a2a5621 100644 --- a/ext/js/display/display-generator.js +++ b/ext/js/display/display-generator.js @@ -626,7 +626,7 @@ export class DisplayGenerator {          n1.appendChild(tag);          let hasTags = false; -        for (const {tags} of pronunciations) { +        for (const {pronunciation: {tags}} of pronunciations) {              if (tags.length > 0) {                  hasTags = true;                  break; @@ -645,8 +645,52 @@ export class DisplayGenerator {       * @returns {HTMLElement}       */      _createPronunciation(details) { +        const {pronunciation} = details; +        switch (pronunciation.type) { +            case 'pitch-accent': +                return this._createPronunciationPitchAccent(pronunciation, details); +            case 'phonetic-transcription': +                return this._createPronunciationPhoneticTranscription(pronunciation, details); +        } +    } + + +    /** +     * @param {import('dictionary').PhoneticTranscription} pronunciation +     * @param {import('dictionary-data-util').GroupedPronunciation} details +     * @returns {HTMLElement} +     */ +    _createPronunciationPhoneticTranscription(pronunciation, details) { +        const {ipa, tags} = pronunciation; +        const {exclusiveTerms, exclusiveReadings} = details; + +        const node = this._instantiate('pronunciation'); + +        node.dataset.tagCount = `${tags.length}`; + +        let n = this._querySelector(node, '.pronunciation-tag-list'); +        this._appendMultiple(n, this._createTag.bind(this), tags); + +        n = this._querySelector(node, '.pronunciation-disambiguation-list'); +        this._createPronunciationDisambiguations(n, exclusiveTerms, exclusiveReadings); + +        n = this._querySelector(node, '.pronunciation-text-container'); + +        this._setTextContent(n, ipa); + +        return node; +    } + +    /** +     * @param {import('dictionary').PitchAccent} pitchAccent +     * @param {import('dictionary-data-util').GroupedPronunciation} details +     * @returns {HTMLElement} +     */ +    _createPronunciationPitchAccent(pitchAccent, details) {          const jp = this._japaneseUtil; -        const {reading, position, nasalPositions, devoicePositions, tags, exclusiveTerms, exclusiveReadings} = details; + +        const {position, nasalPositions, devoicePositions, tags} = pitchAccent; +        const {reading, exclusiveTerms, exclusiveReadings} = details;          const morae = jp.getKanaMorae(reading);          const node = this._instantiate('pronunciation'); @@ -666,6 +710,7 @@ export class DisplayGenerator {          n.appendChild(this._pronunciationGenerator.createPronunciationDownstepPosition(position));          n = this._querySelector(node, '.pronunciation-text-container'); +          n.lang = 'ja';          n.appendChild(this._pronunciationGenerator.createPronunciationText(morae, position, nasalPositions, devoicePositions)); @@ -954,20 +999,21 @@ export class DisplayGenerator {      /**       * @param {string} reading -     * @param {import('dictionary').TermPronunciation[]} pronunciations +     * @param {import('dictionary').TermPronunciation[]} termPronunciations       * @param {string[]} wordClasses       * @param {number} headwordIndex       * @returns {?string}       */ -    _getPronunciationCategories(reading, pronunciations, wordClasses, headwordIndex) { -        if (pronunciations.length === 0) { return null; } +    _getPronunciationCategories(reading, termPronunciations, wordClasses, headwordIndex) { +        if (termPronunciations.length === 0) { return null; }          const isVerbOrAdjective = DictionaryDataUtil.isNonNounVerbOrAdjective(wordClasses);          /** @type {Set<import('japanese-util').PitchCategory>} */          const categories = new Set(); -        for (const pronunciation of pronunciations) { -            if (pronunciation.headwordIndex !== headwordIndex) { continue; } -            for (const {position} of pronunciation.pitches) { -                const category = this._japaneseUtil.getPitchCategory(reading, position, isVerbOrAdjective); +        for (const termPronunciation of termPronunciations) { +            if (termPronunciation.headwordIndex !== headwordIndex) { continue; } +            for (const pronunciation of termPronunciation.pronunciations) { +                if (pronunciation.type !== 'pitch-accent') { continue; } +                const category = this._japaneseUtil.getPitchCategory(reading, pronunciation.position, isVerbOrAdjective);                  if (category !== null) {                      categories.add(category);                  } diff --git a/ext/js/language/translator.js b/ext/js/language/translator.js index 45909940..733955c2 100644 --- a/ext/js/language/translator.js +++ b/ext/js/language/translator.js @@ -964,7 +964,7 @@ export class Translator {                      case 'pitch':                          {                              if (data.reading !== reading) { continue; } -                            /** @type {import('dictionary').TermPitch[]} */ +                            /** @type {import('dictionary').PitchAccent[]} */                              const pitches = [];                              for (const {position, tags, nasal, devoice} of data.pitches) {                                  /** @type {import('dictionary').Tag[]} */ @@ -974,7 +974,13 @@ export class Translator {                                  }                                  const nasalPositions = this._toNumberArray(nasal);                                  const devoicePositions = this._toNumberArray(devoice); -                                pitches.push({position, nasalPositions, devoicePositions, tags: tags2}); +                                pitches.push({ +                                    type: 'pitch-accent', +                                    position, +                                    nasalPositions, +                                    devoicePositions, +                                    tags: tags2 +                                });                              }                              for (const {pronunciations, headwordIndex} of targets) {                                  pronunciations.push(this._createTermPronunciation( @@ -988,6 +994,34 @@ export class Translator {                              }                          }                          break; +                    case 'ipa': +                    { +                        if (data.reading !== reading) { continue; } +                        /** @type {import('dictionary').PhoneticTranscription[]} */ +                        const phoneticTranscriptions = []; +                        for (const {ipa, tags} of data.transcriptions) { +                            /** @type {import('dictionary').Tag[]} */ +                            const tags2 = []; +                            if (Array.isArray(tags)) { +                                tagAggregator.addTags(tags2, dictionary, tags); +                            } +                            phoneticTranscriptions.push({ +                                type: 'phonetic-transcription', +                                ipa, +                                tags: tags2 +                            }); +                        } +                        for (const {pronunciations, headwordIndex} of targets) { +                            pronunciations.push(this._createTermPronunciation( +                                pronunciations.length, +                                headwordIndex, +                                dictionary, +                                dictionaryIndex, +                                dictionaryPriority, +                                phoneticTranscriptions +                            )); +                        } +                    }                  }              }          } @@ -1341,11 +1375,11 @@ export class Translator {       * @param {string} dictionary       * @param {number} dictionaryIndex       * @param {number} dictionaryPriority -     * @param {import('dictionary').TermPitch[]} pitches +     * @param {import('dictionary').Pronunciation[]} pronunciations       * @returns {import('dictionary').TermPronunciation}       */ -    _createTermPronunciation(index, headwordIndex, dictionary, dictionaryIndex, dictionaryPriority, pitches) { -        return {index, headwordIndex, dictionary, dictionaryIndex, dictionaryPriority, pitches}; +    _createTermPronunciation(index, headwordIndex, dictionary, dictionaryIndex, dictionaryPriority, pronunciations) { +        return {index, headwordIndex, dictionary, dictionaryIndex, dictionaryPriority, pronunciations};      }      /** diff --git a/ext/js/pages/settings/anki-controller.js b/ext/js/pages/settings/anki-controller.js index 6f357680..aea94b65 100644 --- a/ext/js/pages/settings/anki-controller.js +++ b/ext/js/pages/settings/anki-controller.js @@ -145,6 +145,7 @@ export class AnkiController {                      'pitch-accents',                      'pitch-accent-graphs',                      'pitch-accent-positions', +                    'phonetic-transcriptions',                      'reading',                      'screenshot',                      'search-query', diff --git a/ext/js/templates/sandbox/anki-template-renderer.js b/ext/js/templates/sandbox/anki-template-renderer.js index 57725bcb..15810239 100644 --- a/ext/js/templates/sandbox/anki-template-renderer.js +++ b/ext/js/templates/sandbox/anki-template-renderer.js @@ -543,12 +543,13 @@ export class AnkiTemplateRenderer {          const [data] = /** @type {[data: import('anki-templates').NoteData]} */ (args);          const {dictionaryEntry} = data;          if (dictionaryEntry.type !== 'term') { return []; } -        const {pronunciations, headwords} = dictionaryEntry; +        const {pronunciations: termPronunciations, headwords} = dictionaryEntry;          /** @type {Set<string>} */          const categories = new Set(); -        for (const {headwordIndex, pitches} of pronunciations) { +        for (const {headwordIndex, pronunciations} of termPronunciations) {              const {reading, wordClasses} = headwords[headwordIndex];              const isVerbOrAdjective = DictionaryDataUtil.isNonNounVerbOrAdjective(wordClasses); +            const pitches = DictionaryDataUtil.getPronunciationsOfType(pronunciations, 'pitch-accent');              for (const {position} of pitches) {                  const category = this._japaneseUtil.getPitchCategory(reading, position, isVerbOrAdjective);                  if (category !== null) { |