aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/css/display.css30
-rw-r--r--ext/data/schemas/dictionary-term-bank-v3-schema.json20
-rw-r--r--ext/data/schemas/options-schema.json7
-rw-r--r--ext/data/templates/anki-field-templates-upgrade-v24.handlebars52
-rw-r--r--ext/data/templates/default-anki-field-templates.handlebars22
-rw-r--r--ext/display-templates.html3
-rw-r--r--ext/js/background/backend.js8
-rw-r--r--ext/js/data/options-util.js17
-rw-r--r--ext/js/data/sandbox/anki-note-data-creator.js4
-rw-r--r--ext/js/dictionary/dictionary-importer.js2
-rw-r--r--ext/js/display/display-generator.js46
-rw-r--r--ext/js/language/deinflector.js2
-rw-r--r--ext/js/language/translator.js235
-rw-r--r--ext/js/pages/settings/dictionary-controller.js10
-rw-r--r--ext/js/templates/sandbox/anki-template-renderer.js2
-rw-r--r--ext/settings.html18
-rw-r--r--test/data/anki-note-builder-test-results.json36
-rw-r--r--test/data/database-test-cases.json6
-rw-r--r--test/data/dictionaries/valid-dictionary1/term_bank_1.json4
-rw-r--r--test/data/translator-test-inputs.json10
-rw-r--r--test/data/translator-test-results-note-data1.json791
-rw-r--r--test/data/translator-test-results.json837
-rw-r--r--test/options-util.test.js5
-rw-r--r--types/ext/anki-templates.d.ts2
-rw-r--r--types/ext/dictionary-data.d.ts9
-rw-r--r--types/ext/dictionary.d.ts15
-rw-r--r--types/ext/settings.d.ts1
-rw-r--r--types/ext/translation-internal.d.ts5
-rw-r--r--types/ext/translation.d.ts4
29 files changed, 1861 insertions, 342 deletions
diff --git a/ext/css/display.css b/ext/css/display.css
index 49aeaaa5..e0b7ab6d 100644
--- a/ext/css/display.css
+++ b/ext/css/display.css
@@ -809,17 +809,39 @@ button.action-button:active {
/* Inflections */
-.inflection-list {
- display: inline-block;
+.inflection-rule-chains {
+ padding-inline-start: 0;
+ list-style-type: none;
+}
+.inflection-rule-chain {
color: var(--reason-text-color);
}
-.inflection-list:empty {
+.inflection-rule-chain:empty {
display: none;
}
-.inflection-list>.inflection+.inflection-separator+.inflection::before {
+.inflection-rule-chain>.inflection+.inflection-separator+.inflection::before {
content: var(--inflection-separator);
padding: 0 0.25em;
}
+.inflection-source-icon {
+ display: inline-block;
+ white-space: nowrap;
+ text-align: center;
+ width: 1.4em;
+ margin-right: 0.2em;
+}
+.inflection-source-icon[data-inflection-source='dictionary']::after {
+ content: '📖';
+}
+.inflection-source-icon[data-inflection-source='algorithm']::after {
+ content: '🧩';
+}
+.inflection-source-icon[data-inflection-source='both'] {
+ width: 2.8em;
+}
+.inflection-source-icon[data-inflection-source='both']::after {
+ content: '🧩📖';
+}
/* Headwords */
diff --git a/ext/data/schemas/dictionary-term-bank-v3-schema.json b/ext/data/schemas/dictionary-term-bank-v3-schema.json
index 8243f2a7..066229c3 100644
--- a/ext/data/schemas/dictionary-term-bank-v3-schema.json
+++ b/ext/data/schemas/dictionary-term-bank-v3-schema.json
@@ -400,7 +400,7 @@
},
{
"type": "string",
- "description": "String of space-separated rule identifiers for the definition which is used to validate delinflection. Valid rule identifiers are: v1: ichidan verb; v5: godan verb; vs: suru verb; vk: kuru verb; adj-i: i-adjective. An empty string corresponds to words which aren't inflected, such as nouns."
+ "description": "String of space-separated rule identifiers for the definition which is used to validate deinflection. An empty string should be used for words which aren't inflected."
},
{
"type": "number",
@@ -535,6 +535,24 @@
}
}
]
+ },
+ {
+ "type": "array",
+ "description": "Deinflection of the term to an uninflected term.",
+ "items": [
+ {
+ "type": "string",
+ "description": "The uninflected term."
+ },
+ {
+ "type": "array",
+ "description": "A chain of inflection rules that produced the inflected term",
+ "items": {
+ "type": "string",
+ "description": "A single inflection rule."
+ }
+ }
+ ]
}
]
}
diff --git a/ext/data/schemas/options-schema.json b/ext/data/schemas/options-schema.json
index 8cf00400..24f3a6b0 100644
--- a/ext/data/schemas/options-schema.json
+++ b/ext/data/schemas/options-schema.json
@@ -823,7 +823,8 @@
"enabled",
"allowSecondarySearches",
"definitionsCollapsible",
- "partsOfSpeechFilter"
+ "partsOfSpeechFilter",
+ "useDeinflections"
],
"properties": {
"name": {
@@ -850,6 +851,10 @@
"partsOfSpeechFilter": {
"type": "boolean",
"default": true
+ },
+ "useDeinflections": {
+ "type": "boolean",
+ "default": true
}
}
}
diff --git a/ext/data/templates/anki-field-templates-upgrade-v24.handlebars b/ext/data/templates/anki-field-templates-upgrade-v24.handlebars
new file mode 100644
index 00000000..2288737c
--- /dev/null
+++ b/ext/data/templates/anki-field-templates-upgrade-v24.handlebars
@@ -0,0 +1,52 @@
+{{#*inline "phonetic-transcriptions"}}
+ {{~#if (op ">" definition.phoneticTranscriptions.length 0)~}}
+ <ul>
+ {{~#each definition.phoneticTranscriptions~}}
+ {{~#each phoneticTranscriptions~}}
+ <li>
+ {{~set "any" false~}}
+ {{~#each tags~}}
+ {{~#if (get "any")}}, {{else}}<i>({{/if~}}
+ {{name}}
+ {{~set "any" true~}}
+ {{~/each~}}
+ {{~#if (get "any")}})</i> {{/if~}}
+ {{ipa~}}
+ </li>
+ {{~/each~}}
+ {{~/each~}}
+ </ul>
+ {{~/if~}}
+{{/inline}}
+
+{{<<<<<<<}}
+{{#*inline "conjugation"}}
+ {{~#if (op ">" definition.inflectionRuleChainCandidates.length 0)~}}
+ {{~set "multiple" false~}}
+ {{~#if (op ">" definition.inflectionRuleChainCandidates.length 1)~}}
+ {{~set "multiple" true~}}
+ {{~/if~}}
+ {{~#if (get "multiple")~}}<ul>{{/if~}}
+ {{~#each definition.inflectionRuleChainCandidates~}}
+ {{~#if (op ">" inflectionRules.length 0)~}}
+ {{~#if (get "multiple")~}}<li>{{/if~}}
+ {{~#each inflectionRules~}}
+ {{~#if (op ">" @index 0)}} « {{/if~}}
+ {{.}}
+ {{~/each~}}
+ {{~#if (get "multiple")~}}</li>{{/if~}}
+ {{~/if~}}
+ {{~/each~}}
+ {{~#if (get "multiple")~}}</ul>{{/if~}}
+ {{~/if~}}
+{{/inline}}
+{{=======}}
+{{#*inline "conjugation"}}
+ {{~#if definition.reasons~}}
+ {{~#each definition.reasons~}}
+ {{~#if (op ">" @index 0)}} « {{/if~}}
+ {{.}}
+ {{~/each~}}
+ {{~/if~}}
+{{/inline}}
+{{>>>>>>>>}}
diff --git a/ext/data/templates/default-anki-field-templates.handlebars b/ext/data/templates/default-anki-field-templates.handlebars
index f23b9d0b..818677ce 100644
--- a/ext/data/templates/default-anki-field-templates.handlebars
+++ b/ext/data/templates/default-anki-field-templates.handlebars
@@ -261,11 +261,23 @@
{{/inline}}
{{#*inline "conjugation"}}
- {{~#if definition.reasons~}}
- {{~#each definition.reasons~}}
- {{~#if (op ">" @index 0)}} « {{/if~}}
- {{.}}
- {{~/each~}}
+ {{~#if (op ">" definition.inflectionRuleChainCandidates.length 0)~}}
+ {{~set "multiple" false~}}
+ {{~#if (op ">" definition.inflectionRuleChainCandidates.length 1)~}}
+ {{~set "multiple" true~}}
+ {{~/if~}}
+ {{~#if (get "multiple")~}}<ul>{{/if~}}
+ {{~#each definition.inflectionRuleChainCandidates~}}
+ {{~#if (op ">" inflectionRules.length 0)~}}
+ {{~#if (get "multiple")~}}<li>{{/if~}}
+ {{~#each inflectionRules~}}
+ {{~#if (op ">" @index 0)}} « {{/if~}}
+ {{.}}
+ {{~/each~}}
+ {{~#if (get "multiple")~}}</li>{{/if~}}
+ {{~/if~}}
+ {{~/each~}}
+ {{~#if (get "multiple")~}}</ul>{{/if~}}
{{~/if~}}
{{/inline}}
diff --git a/ext/display-templates.html b/ext/display-templates.html
index ed0037bb..a50cea3b 100644
--- a/ext/display-templates.html
+++ b/ext/display-templates.html
@@ -32,7 +32,7 @@
<div class="headword-list"></div>
<div class="headword-list-details">
<div class="headword-list-tag-list tag-list"></div>
- <div class="inflection-list"></div>
+ <ul class="inflection-rule-chains"></ul>
</div>
</div>
<div class="entry-body">
@@ -77,6 +77,7 @@
<template id="definition-disambiguation-template"><span class="definition-disambiguation"></span></template>
<template id="gloss-item-template"><li class="gloss-item click-scannable"><span class="gloss-separator"> </span><span class="gloss-content"></span></li></template>
<template id="gloss-item-image-description-template"> <span class="gloss-image-description"></span></template>
+<template id="inflection-rule-chain-template"><li class="inflection-rule-chain"></li></template>
<template id="inflection-template"><span class="inflection"></span><span class="inflection-separator"> </span></template>
<!-- Frequency templates -->
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js
index a5a42272..bc4f222f 100644
--- a/ext/js/background/backend.js
+++ b/ext/js/background/backend.js
@@ -2428,7 +2428,8 @@ export class Backend {
index: enabledDictionaryMap.size,
priority: 0,
allowSecondarySearches: false,
- partsOfSpeechFilter: true
+ partsOfSpeechFilter: true,
+ useDeinflections: true
});
excludeDictionaryDefinitions = new Set();
excludeDictionaryDefinitions.add(mainDictionary);
@@ -2474,12 +2475,13 @@ export class Backend {
const enabledDictionaryMap = new Map();
for (const dictionary of options.dictionaries) {
if (!dictionary.enabled) { continue; }
- const {name, priority, allowSecondarySearches, partsOfSpeechFilter} = dictionary;
+ const {name, priority, allowSecondarySearches, partsOfSpeechFilter, useDeinflections} = dictionary;
enabledDictionaryMap.set(name, {
index: enabledDictionaryMap.size,
priority,
allowSecondarySearches,
- partsOfSpeechFilter
+ partsOfSpeechFilter,
+ useDeinflections
});
}
return enabledDictionaryMap;
diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js
index c93e261d..0aabed6f 100644
--- a/ext/js/data/options-util.js
+++ b/ext/js/data/options-util.js
@@ -556,7 +556,8 @@ export class OptionsUtil {
this._updateVersion20,
this._updateVersion21,
this._updateVersion22,
- this._updateVersion23
+ this._updateVersion23,
+ this._updateVersion24
];
if (typeof targetVersion === 'number' && targetVersion < result.length) {
result.splice(targetVersion);
@@ -1156,6 +1157,20 @@ export class OptionsUtil {
}
/**
+ * - Added dictionaries[].useDeinflections.
+ * @type {import('options-util').UpdateFunction}
+ */
+ async _updateVersion24(options) {
+ await this._applyAnkiFieldTemplatesPatch(options, '/data/templates/anki-field-templates-upgrade-v24.handlebars');
+
+ for (const {options: profileOptions} of options.profiles) {
+ for (const dictionary of profileOptions.dictionaries) {
+ dictionary.useDeinflections = true;
+ }
+ }
+ }
+
+ /**
* @param {string} url
* @returns {Promise<chrome.tabs.Tab>}
*/
diff --git a/ext/js/data/sandbox/anki-note-data-creator.js b/ext/js/data/sandbox/anki-note-data-creator.js
index c0a11869..77d6e357 100644
--- a/ext/js/data/sandbox/anki-note-data-creator.js
+++ b/ext/js/data/sandbox/anki-note-data-creator.js
@@ -376,7 +376,7 @@ export class AnkiNoteDataCreator {
case 'merge': type = 'termMerged'; break;
}
- const {inflections, score, dictionaryIndex, dictionaryPriority, sourceTermExactMatchCount, definitions} = dictionaryEntry;
+ const {inflectionRuleChainCandidates, score, dictionaryIndex, dictionaryPriority, sourceTermExactMatchCount, definitions} = dictionaryEntry;
let {url} = context;
if (typeof url !== 'string') { url = ''; }
@@ -401,7 +401,7 @@ export class AnkiNoteDataCreator {
source: (primarySource !== null ? primarySource.transformedText : null),
rawSource: (primarySource !== null ? primarySource.originalText : null),
sourceTerm: (type !== 'termMerged' ? (primarySource !== null ? primarySource.deinflectedText : null) : void 0),
- reasons: inflections,
+ inflectionRuleChainCandidates,
score,
isPrimary: (type === 'term' ? dictionaryEntry.isPrimary : void 0),
get sequence() { return self.getCachedValue(sequence); },
diff --git a/ext/js/dictionary/dictionary-importer.js b/ext/js/dictionary/dictionary-importer.js
index bfd7a8b2..8df7860e 100644
--- a/ext/js/dictionary/dictionary-importer.js
+++ b/ext/js/dictionary/dictionary-importer.js
@@ -160,7 +160,7 @@ export class DictionaryImporter {
const glossaryList = entry.glossary;
for (let j = 0, jj = glossaryList.length; j < jj; ++j) {
const glossary = glossaryList[j];
- if (typeof glossary !== 'object' || glossary === null) { continue; }
+ if (typeof glossary !== 'object' || glossary === null || Array.isArray(glossary)) { continue; }
glossaryList[j] = this._formatDictionaryTermGlossaryObject(glossary, entry, requirements);
}
if ((i % formatProgressInterval) === 0) {
diff --git a/ext/js/display/display-generator.js b/ext/js/display/display-generator.js
index 3a2a5621..521cbb41 100644
--- a/ext/js/display/display-generator.js
+++ b/ext/js/display/display-generator.js
@@ -67,13 +67,13 @@ export class DisplayGenerator {
const node = this._instantiate('term-entry');
const headwordsContainer = this._querySelector(node, '.headword-list');
- const inflectionsContainer = this._querySelector(node, '.inflection-list');
+ const inflectionRuleChainsContainer = this._querySelector(node, '.inflection-rule-chains');
const groupedPronunciationsContainer = this._querySelector(node, '.pronunciation-group-list');
const frequencyGroupListContainer = this._querySelector(node, '.frequency-group-list');
const definitionsContainer = this._querySelector(node, '.definition-list');
const headwordTagsContainer = this._querySelector(node, '.headword-list-tag-list');
- const {headwords, type, inflections, definitions, frequencies, pronunciations} = dictionaryEntry;
+ const {headwords, type, inflectionRuleChainCandidates, definitions, frequencies, pronunciations} = dictionaryEntry;
const groupedPronunciations = DictionaryDataUtil.getGroupedPronunciations(dictionaryEntry);
const pronunciationCount = groupedPronunciations.reduce((i, v) => i + v.pronunciations.length, 0);
const groupedFrequencies = DictionaryDataUtil.groupTermFrequencies(dictionaryEntry);
@@ -112,7 +112,7 @@ export class DisplayGenerator {
}
headwordsContainer.dataset.count = `${headwords.length}`;
- this._appendMultiple(inflectionsContainer, this._createTermInflection.bind(this), inflections);
+ this._appendMultiple(inflectionRuleChainsContainer, this._createInflectionRuleChain.bind(this), inflectionRuleChainCandidates);
this._appendMultiple(frequencyGroupListContainer, this._createFrequencyGroup.bind(this), groupedFrequencies, false);
this._appendMultiple(groupedPronunciationsContainer, this._createGroupedPronunciation.bind(this), groupedPronunciations);
this._appendMultiple(headwordTagsContainer, this._createTermTag.bind(this), termTags, headwords.length);
@@ -357,6 +357,44 @@ export class DisplayGenerator {
}
/**
+ * @param {import('dictionary').InflectionRuleChainCandidate} inflectionRuleChain
+ * @returns {?HTMLElement}
+ */
+ _createInflectionRuleChain(inflectionRuleChain) {
+ const {source, inflectionRules} = inflectionRuleChain;
+ if (!Array.isArray(inflectionRules) || inflectionRules.length === 0) { return null; }
+ const fragment = this._instantiate('inflection-rule-chain');
+
+ const sourceIcon = this._getInflectionSourceIcon(source);
+
+ fragment.appendChild(sourceIcon);
+
+ this._appendMultiple(fragment, this._createTermInflection.bind(this), inflectionRules);
+ return fragment;
+ }
+
+ /**
+ * @param {import('dictionary').InflectionSource} source
+ * @returns {HTMLElement}
+ */
+ _getInflectionSourceIcon(source) {
+ const icon = document.createElement('span');
+ icon.classList.add('inflection-source-icon');
+ icon.dataset.inflectionSource = source;
+ switch (source) {
+ case 'dictionary':
+ icon.title = 'Dictionary Deinflection';
+ return icon;
+ case 'algorithm':
+ icon.title = 'Algorithm Deinflection';
+ return icon;
+ case 'both':
+ icon.title = 'Dictionary and Algorithm Deinflection';
+ return icon;
+ }
+ }
+
+ /**
* @param {string} inflection
* @returns {DocumentFragment}
*/
@@ -396,7 +434,7 @@ export class DisplayGenerator {
}
/**
- * @param {import('dictionary-data').TermGlossary} entry
+ * @param {import('dictionary-data').TermGlossaryContent} entry
* @param {string} dictionary
* @returns {?HTMLElement}
*/
diff --git a/ext/js/language/deinflector.js b/ext/js/language/deinflector.js
index d2d92e53..e2b66cb4 100644
--- a/ext/js/language/deinflector.js
+++ b/ext/js/language/deinflector.js
@@ -80,7 +80,7 @@ export class Deinflector {
/**
* @param {string} term
* @param {import('translation-internal').DeinflectionRuleFlags} rules
- * @param {string[]} reasons
+ * @param {import('dictionary').InflectionRuleChain} reasons
* @returns {import('translation-internal').Deinflection}
*/
_createDeinflection(term, rules, reasons) {
diff --git a/ext/js/language/translator.js b/ext/js/language/translator.js
index 5441294b..89a3e5ec 100644
--- a/ext/js/language/translator.js
+++ b/ext/js/language/translator.js
@@ -70,7 +70,7 @@ export class Translator {
async findTerms(mode, text, options) {
const {enabledDictionaryMap, excludeDictionaryDefinitions, sortFrequencyDictionary, sortFrequencyDictionaryOrder} = options;
const tagAggregator = new TranslatorTagAggregator();
- let {dictionaryEntries, originalTextLength} = await this._findTermsInternalWrapper(text, enabledDictionaryMap, options, tagAggregator);
+ let {dictionaryEntries, originalTextLength} = await this._findTermsInternal(text, enabledDictionaryMap, options, tagAggregator);
switch (mode) {
case 'group':
@@ -208,7 +208,7 @@ export class Translator {
* @param {TranslatorTagAggregator} tagAggregator
* @returns {Promise<import('translator').FindTermsResult>}
*/
- async _findTermsInternalWrapper(text, enabledDictionaryMap, options, tagAggregator) {
+ async _findTermsInternal(text, enabledDictionaryMap, options, tagAggregator) {
if (options.removeNonJapaneseCharacters) {
text = this._getJapaneseOnlyText(text);
}
@@ -216,18 +216,30 @@ export class Translator {
return {dictionaryEntries: [], originalTextLength: 0};
}
- const deinflections = await this._findTermsInternal(text, enabledDictionaryMap, options);
+ const deinflections = await this._getDeinflections(text, enabledDictionaryMap, options);
let originalTextLength = 0;
+ /** @type {import('dictionary').TermDictionaryEntry[]} */
const dictionaryEntries = [];
const ids = new Set();
- for (const {databaseEntries, originalText, transformedText, deinflectedText, reasons} of deinflections) {
+ for (const {databaseEntries, originalText, transformedText, deinflectedText, inflectionRuleChainCandidates} of deinflections) {
if (databaseEntries.length === 0) { continue; }
originalTextLength = Math.max(originalTextLength, originalText.length);
for (const databaseEntry of databaseEntries) {
const {id} = databaseEntry;
- if (ids.has(id)) { continue; }
- const dictionaryEntry = this._createTermDictionaryEntryFromDatabaseEntry(databaseEntry, originalText, transformedText, deinflectedText, reasons, true, enabledDictionaryMap, tagAggregator);
+ if (ids.has(id)) {
+ const existingEntry = dictionaryEntries.find((entry) => {
+ return entry.definitions.some((definition) => definition.id === id);
+ });
+
+ if (existingEntry && transformedText.length >= existingEntry.headwords[0].sources[0].transformedText.length) {
+ this._mergeInflectionRuleChains(existingEntry, inflectionRuleChainCandidates);
+ }
+
+ continue;
+ }
+
+ const dictionaryEntry = this._createTermDictionaryEntryFromDatabaseEntry(databaseEntry, originalText, transformedText, deinflectedText, inflectionRuleChainCandidates, true, enabledDictionaryMap, tagAggregator);
dictionaryEntries.push(dictionaryEntry);
ids.add(id);
}
@@ -237,40 +249,163 @@ export class Translator {
}
/**
+ * @param {import('dictionary').TermDictionaryEntry} existingEntry
+ * @param {import('dictionary').InflectionRuleChainCandidate[]} inflectionRuleChainCandidates
+ */
+ _mergeInflectionRuleChains(existingEntry, inflectionRuleChainCandidates) {
+ const existingChains = existingEntry.inflectionRuleChainCandidates;
+
+ for (const {source, inflectionRules} of inflectionRuleChainCandidates) {
+ const duplicate = existingChains.find((existingChain) => this._areArraysEqualIgnoreOrder(existingChain.inflectionRules, inflectionRules));
+ if (!duplicate) {
+ existingEntry.inflectionRuleChainCandidates.push({source, inflectionRules});
+ } else if (duplicate.source !== source) {
+ duplicate.source = 'both';
+ }
+ }
+ }
+
+ /**
+ * @param {string[]} array1
+ * @param {string[]} array2
+ * @returns {boolean}
+ */
+ _areArraysEqualIgnoreOrder(array1, array2) {
+ if (array1.length !== array2.length) {
+ return false;
+ }
+
+ const frequencyCounter = new Map();
+
+ for (const element of array1) {
+ frequencyCounter.set(element, (frequencyCounter.get(element) || 0) + 1);
+ }
+
+ for (const element of array2) {
+ const frequency = frequencyCounter.get(element);
+ if (!frequency) {
+ return false;
+ }
+ frequencyCounter.set(element, frequency - 1);
+ }
+
+ return true;
+ }
+
+
+ /**
* @param {string} text
* @param {Map<string, import('translation').FindTermDictionary>} enabledDictionaryMap
* @param {import('translation').FindTermsOptions} options
* @returns {Promise<import('translation-internal').DatabaseDeinflection[]>}
*/
- async _findTermsInternal(text, enabledDictionaryMap, options) {
- const deinflections = (
+ async _getDeinflections(text, enabledDictionaryMap, options) {
+ let deinflections = (
options.deinflect ?
- this._getAllDeinflections(text, options) :
+ this._getAlgorithmDeinflections(text, options) :
[this._createDeinflection(text, text, text, 0, [])]
);
if (deinflections.length === 0) { return []; }
- const uniqueDeinflectionTerms = [];
- const uniqueDeinflectionArrays = [];
- const uniqueDeinflectionsMap = new Map();
+ const {matchType} = options;
+
+ await this._addEntriesToDeinflections(deinflections, enabledDictionaryMap, matchType);
+
+ const dictionaryDeinflections = await this._getDictionaryDeinflections(deinflections, enabledDictionaryMap, matchType);
+ deinflections.push(...dictionaryDeinflections);
+
for (const deinflection of deinflections) {
- const term = deinflection.deinflectedText;
- let deinflectionArray = uniqueDeinflectionsMap.get(term);
+ for (const entry of deinflection.databaseEntries) {
+ entry.definitions = entry.definitions.filter((definition) => !Array.isArray(definition));
+ }
+ deinflection.databaseEntries = deinflection.databaseEntries.filter((entry) => entry.definitions.length);
+ }
+ deinflections = deinflections.filter((deinflection) => deinflection.databaseEntries.length);
+
+ return deinflections;
+ }
+
+ /**
+ * @param {import('translation-internal').DatabaseDeinflection[]} deinflections
+ * @param {Map<string, import('translation').FindTermDictionary>} enabledDictionaryMap
+ * @param {import('dictionary').TermSourceMatchType} matchType
+ * @returns {Promise<import('translation-internal').DatabaseDeinflection[]>}
+ */
+ async _getDictionaryDeinflections(deinflections, enabledDictionaryMap, matchType) {
+ /** @type {import('translation-internal').DatabaseDeinflection[]} */
+ const dictionaryDeinflections = [];
+ for (const deinflection of deinflections) {
+ const {originalText, transformedText, inflectionRuleChainCandidates: algorithmChains, databaseEntries} = deinflection;
+ for (const entry of databaseEntries) {
+ const {dictionary, definitions} = entry;
+ const entryDictionary = enabledDictionaryMap.get(dictionary);
+ const useDeinflections = entryDictionary?.useDeinflections ?? true;
+ if (!useDeinflections) { continue; }
+ for (const definition of definitions) {
+ if (Array.isArray(definition)) {
+ const [formOf, inflectionRules] = definition;
+ if (!formOf) { continue; }
+
+ const inflectionRuleChainCandidates = algorithmChains.map(({inflectionRules: algInflections}) => {
+ return {
+ source: /** @type {import('dictionary').InflectionSource} */ (algInflections.length === 0 ? 'dictionary' : 'both'),
+ inflectionRules: [...algInflections, ...inflectionRules]
+ };
+ });
+
+ const dictionaryDeinflection = this._createDeinflection(originalText, transformedText, formOf, 0, inflectionRuleChainCandidates);
+ dictionaryDeinflections.push(dictionaryDeinflection);
+ }
+ }
+ }
+ }
+
+ await this._addEntriesToDeinflections(dictionaryDeinflections, enabledDictionaryMap, matchType);
+
+ return dictionaryDeinflections;
+ }
+
+ /**
+ * @param {import('translation-internal').DatabaseDeinflection[]} deinflections
+ * @param {Map<string, import('translation').FindTermDictionary>} enabledDictionaryMap
+ * @param {import('dictionary').TermSourceMatchType} matchType
+ */
+ async _addEntriesToDeinflections(deinflections, enabledDictionaryMap, matchType) {
+ const uniqueDeinflectionsMap = this._groupDeinflectionsByTerm(deinflections);
+ const uniqueDeinflectionArrays = [...uniqueDeinflectionsMap.values()];
+ const uniqueDeinflectionTerms = [...uniqueDeinflectionsMap.keys()];
+
+ const databaseEntries = await this._database.findTermsBulk(uniqueDeinflectionTerms, enabledDictionaryMap, matchType);
+ this._matchEntriesToDeinflections(databaseEntries, uniqueDeinflectionArrays, enabledDictionaryMap);
+ }
+
+ /**
+ * @param {import('translation-internal').DatabaseDeinflection[]} deinflections
+ * @returns {Map<string, import('translation-internal').DatabaseDeinflection[]>}
+ */
+ _groupDeinflectionsByTerm(deinflections) {
+ const result = new Map();
+ for (const deinflection of deinflections) {
+ const {deinflectedText} = deinflection;
+ let deinflectionArray = result.get(deinflectedText);
if (typeof deinflectionArray === 'undefined') {
deinflectionArray = [];
- uniqueDeinflectionTerms.push(term);
- uniqueDeinflectionArrays.push(deinflectionArray);
- uniqueDeinflectionsMap.set(term, deinflectionArray);
+ result.set(deinflectedText, deinflectionArray);
}
deinflectionArray.push(deinflection);
}
+ return result;
+ }
- const {matchType} = options;
- const databaseEntries = await this._database.findTermsBulk(uniqueDeinflectionTerms, enabledDictionaryMap, matchType);
-
+ /**
+ * @param {import('dictionary-database').TermEntry[]} databaseEntries
+ * @param {import('translation-internal').DatabaseDeinflection[][]} uniqueDeinflectionArrays
+ * @param {Map<string, import('translation').FindTermDictionary>} enabledDictionaryMap
+ */
+ _matchEntriesToDeinflections(databaseEntries, uniqueDeinflectionArrays, enabledDictionaryMap) {
for (const databaseEntry of databaseEntries) {
const entryDictionary = /** @type {import('translation').FindTermDictionary} */ (enabledDictionaryMap.get(databaseEntry.dictionary));
- const partsOfSpeechFilter = entryDictionary.partsOfSpeechFilter;
+ const {partsOfSpeechFilter} = entryDictionary;
const definitionRules = Deinflector.rulesToRuleFlags(databaseEntry.rules);
for (const deinflection of uniqueDeinflectionArrays[databaseEntry.index]) {
@@ -280,8 +415,6 @@ export class Translator {
}
}
}
-
- return deinflections;
}
// Deinflections and text transformations
@@ -291,7 +424,7 @@ export class Translator {
* @param {import('translation').FindTermsOptions} options
* @returns {import('translation-internal').DatabaseDeinflection[]}
*/
- _getAllDeinflections(text, options) {
+ _getAlgorithmDeinflections(text, options) {
/** @type {import('translation-internal').TextDeinflectionOptionsArrays} */
const textOptionVariantArray = [
this._getTextReplacementsVariants(options),
@@ -342,7 +475,12 @@ export class Translator {
used.add(source);
const rawSource = sourceMap.source.substring(0, sourceMap.getSourceLength(i));
for (const {term, rules, reasons} of /** @type {Deinflector} */ (this._deinflector).deinflect(source)) {
- deinflections.push(this._createDeinflection(rawSource, source, term, rules, reasons));
+ /** @type {import('dictionary').InflectionRuleChainCandidate} */
+ const inflectionRuleChainCandidate = {
+ source: 'algorithm',
+ inflectionRules: reasons
+ };
+ deinflections.push(this._createDeinflection(rawSource, source, term, rules, [inflectionRuleChainCandidate]));
}
}
}
@@ -435,11 +573,11 @@ export class Translator {
* @param {string} transformedText
* @param {string} deinflectedText
* @param {import('translation-internal').DeinflectionRuleFlags} rules
- * @param {string[]} reasons
+ * @param {import('dictionary').InflectionRuleChainCandidate[]} inflectionRuleChainCandidates
* @returns {import('translation-internal').DatabaseDeinflection}
*/
- _createDeinflection(originalText, transformedText, deinflectedText, rules, reasons) {
- return {originalText, transformedText, deinflectedText, rules, reasons, databaseEntries: []};
+ _createDeinflection(originalText, transformedText, deinflectedText, rules, inflectionRuleChainCandidates) {
+ return {originalText, transformedText, deinflectedText, rules, inflectionRuleChainCandidates, databaseEntries: []};
}
// Term dictionary entry grouping
@@ -597,8 +735,8 @@ export class Translator {
_groupDictionaryEntriesByHeadword(dictionaryEntries, tagAggregator) {
const groups = new Map();
for (const dictionaryEntry of dictionaryEntries) {
- const {inflections, headwords: [{term, reading}]} = dictionaryEntry;
- const key = this._createMapKey([term, reading, ...inflections]);
+ const {inflectionRuleChainCandidates, headwords: [{term, reading}]} = dictionaryEntry;
+ const key = this._createMapKey([term, reading, ...inflectionRuleChainCandidates]);
let groupDictionaryEntries = groups.get(key);
if (typeof groupDictionaryEntries === 'undefined') {
groupDictionaryEntries = [];
@@ -1370,7 +1508,7 @@ export class Translator {
* @param {number[]} sequences
* @param {boolean} isPrimary
* @param {import('dictionary').Tag[]} tags
- * @param {import('dictionary-data').TermGlossary[]} entries
+ * @param {import('dictionary-data').TermGlossaryContent[]} entries
* @returns {import('dictionary').TermDefinition}
*/
_createTermDefinition(index, headwordIndices, dictionary, dictionaryIndex, dictionaryPriority, id, score, sequences, isPrimary, tags, entries) {
@@ -1421,7 +1559,7 @@ export class Translator {
/**
* @param {boolean} isPrimary
- * @param {string[]} inflections
+ * @param {import('dictionary').InflectionRuleChainCandidate[]} inflectionRuleChainCandidates
* @param {number} score
* @param {number} dictionaryIndex
* @param {number} dictionaryPriority
@@ -1431,11 +1569,11 @@ export class Translator {
* @param {import('dictionary').TermDefinition[]} definitions
* @returns {import('dictionary').TermDictionaryEntry}
*/
- _createTermDictionaryEntry(isPrimary, inflections, score, dictionaryIndex, dictionaryPriority, sourceTermExactMatchCount, maxTransformedTextLength, headwords, definitions) {
+ _createTermDictionaryEntry(isPrimary, inflectionRuleChainCandidates, score, dictionaryIndex, dictionaryPriority, sourceTermExactMatchCount, maxTransformedTextLength, headwords, definitions) {
return {
type: 'term',
isPrimary,
- inflections,
+ inflectionRuleChainCandidates,
score,
frequencyOrder: 0,
dictionaryIndex,
@@ -1454,14 +1592,29 @@ export class Translator {
* @param {string} originalText
* @param {string} transformedText
* @param {string} deinflectedText
- * @param {string[]} reasons
+ * @param {import('dictionary').InflectionRuleChainCandidate[]} inflectionRuleChainCandidates
* @param {boolean} isPrimary
* @param {Map<string, import('translation').FindTermDictionary>} enabledDictionaryMap
* @param {TranslatorTagAggregator} tagAggregator
* @returns {import('dictionary').TermDictionaryEntry}
*/
- _createTermDictionaryEntryFromDatabaseEntry(databaseEntry, originalText, transformedText, deinflectedText, reasons, isPrimary, enabledDictionaryMap, tagAggregator) {
- const {matchType, matchSource, term, reading: rawReading, definitionTags, termTags, definitions, score, dictionary, id, sequence: rawSequence, rules} = databaseEntry;
+ _createTermDictionaryEntryFromDatabaseEntry(databaseEntry, originalText, transformedText, deinflectedText, inflectionRuleChainCandidates, isPrimary, enabledDictionaryMap, tagAggregator) {
+ const {
+ matchType,
+ matchSource,
+ term,
+ reading: rawReading,
+ definitionTags,
+ termTags,
+ definitions,
+ score,
+ dictionary,
+ id,
+ sequence: rawSequence,
+ rules
+ } = databaseEntry;
+ // cast is safe because getDeinflections filters out deinflection definitions
+ const contentDefinitions = /** @type {import('dictionary-data').TermGlossaryContent[]} */ (definitions);
const reading = (rawReading.length > 0 ? rawReading : term);
const {index: dictionaryIndex, priority: dictionaryPriority} = this._getDictionaryOrder(dictionary, enabledDictionaryMap);
const sourceTermExactMatchCount = (isPrimary && deinflectedText === term ? 1 : 0);
@@ -1479,14 +1632,14 @@ export class Translator {
return this._createTermDictionaryEntry(
isPrimary,
- reasons,
+ inflectionRuleChainCandidates,
score,
dictionaryIndex,
dictionaryPriority,
sourceTermExactMatchCount,
maxTransformedTextLength,
[this._createTermHeadword(0, term, reading, [source], headwordTagGroups, rules)],
- [this._createTermDefinition(0, [0], dictionary, dictionaryIndex, dictionaryPriority, id, score, [sequence], isPrimary, definitionTagGroups, definitions)]
+ [this._createTermDefinition(0, [0], dictionary, dictionaryIndex, dictionaryPriority, id, score, [sequence], isPrimary, definitionTagGroups, contentDefinitions)]
);
}
@@ -1530,7 +1683,7 @@ export class Translator {
if (dictionaryEntry.isPrimary) {
isPrimary = true;
maxTransformedTextLength = Math.max(maxTransformedTextLength, dictionaryEntry.maxTransformedTextLength);
- const dictionaryEntryInflections = dictionaryEntry.inflections;
+ const dictionaryEntryInflections = dictionaryEntry.inflectionRuleChainCandidates;
if (inflections === null || dictionaryEntryInflections.length < inflections.length) {
inflections = dictionaryEntryInflections;
}
@@ -1742,7 +1895,7 @@ export class Translator {
if (i !== 0) { return i; }
// Sort by the number of inflection reasons
- i = v1.inflections.length - v2.inflections.length;
+ i = v1.inflectionRuleChainCandidates.length - v2.inflectionRuleChainCandidates.length;
if (i !== 0) { return i; }
// Sort by how many terms exactly match the source (e.g. for exact kana prioritization)
diff --git a/ext/js/pages/settings/dictionary-controller.js b/ext/js/pages/settings/dictionary-controller.js
index 18a802be..1d3da532 100644
--- a/ext/js/pages/settings/dictionary-controller.js
+++ b/ext/js/pages/settings/dictionary-controller.js
@@ -185,6 +185,10 @@ class DictionaryEntry {
const partsOfSpeechFilterSetting = querySelectorNotNull(modal.node, '.dictionary-parts-of-speech-filter-setting');
/** @type {HTMLElement} */
const partsOfSpeechFilterToggle = querySelectorNotNull(partsOfSpeechFilterSetting, '.dictionary-parts-of-speech-filter-toggle');
+ /** @type {HTMLElement} */
+ const useDeinflectionsSetting = querySelectorNotNull(modal.node, '.dictionary-use-deinflections-setting');
+ /** @type {HTMLElement} */
+ const useDeinflectionsToggle = querySelectorNotNull(useDeinflectionsSetting, '.dictionary-use-deinflections-toggle');
titleElement.textContent = title;
versionElement.textContent = `rev.${revision}`;
@@ -194,6 +198,9 @@ class DictionaryEntry {
partsOfSpeechFilterSetting.hidden = !counts.terms.total;
partsOfSpeechFilterToggle.dataset.setting = `dictionaries[${this._index}].partsOfSpeechFilter`;
+ useDeinflectionsSetting.hidden = !counts.terms.total;
+ useDeinflectionsToggle.dataset.setting = `dictionaries[${this._index}].useDeinflections`;
+
this._setupDetails(detailsTableElement);
modal.setVisible(true);
@@ -521,7 +528,8 @@ export class DictionaryController {
enabled,
allowSecondarySearches: false,
definitionsCollapsible: 'not-collapsible',
- partsOfSpeechFilter: true
+ partsOfSpeechFilter: true,
+ useDeinflections: true
};
}
diff --git a/ext/js/templates/sandbox/anki-template-renderer.js b/ext/js/templates/sandbox/anki-template-renderer.js
index 3311097f..e4822bee 100644
--- a/ext/js/templates/sandbox/anki-template-renderer.js
+++ b/ext/js/templates/sandbox/anki-template-renderer.js
@@ -675,7 +675,7 @@ export class AnkiTemplateRenderer {
* @type {import('template-renderer').HelperFunction<string>}
*/
_formatGlossary(args, _context, options) {
- const [dictionary, content] = /** @type {[dictionary: string, content: import('dictionary-data').TermGlossary]} */ (args);
+ const [dictionary, content] = /** @type {[dictionary: string, content: import('dictionary-data').TermGlossaryContent]} */ (args);
const data = options.data.root;
if (typeof content === 'string') { return this._stringToMultiLineHtml(this._escape(content)); }
if (!(typeof content === 'object' && content !== null)) { return ''; }
diff --git a/ext/settings.html b/ext/settings.html
index 2cc521d5..3a4c90ce 100644
--- a/ext/settings.html
+++ b/ext/settings.html
@@ -2691,6 +2691,24 @@
</div>
</div>
<hr>
+ <div class="settings-item dictionary-use-deinflections-setting" hidden>
+ <div class="settings-item-inner">
+ <div class="settings-item-left">
+ <div class="settings-item-label">
+ Use deinflections
+ <a tabindex="0" class="more-toggle more-only" data-parent-distance="4">(?)</a>
+ </div>
+ </div>
+ <div class="settings-item-right">
+ <label class="toggle"><input type="checkbox" class="dictionary-use-deinflections-toggle"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
+ </div>
+ </div>
+ <div class="settings-item-children more" hidden>
+ Deinflections from this dictionary will be used.
+ <p><a tabindex="0" class="more-toggle" data-parent-distance="3">Hide&hellip;</a></p>
+ </div>
+ </div>
+ <hr>
<div class="settings-item"><div class="settings-item-children">
<div class="dictionary-details-table"></div>
<div class="dictionary-counts"></div>
diff --git a/test/data/anki-note-builder-test-results.json b/test/data/anki-note-builder-test-results.json
index 86bffc6a..7129d748 100644
--- a/test/data/anki-note-builder-test-results.json
+++ b/test/data/anki-note-builder-test-results.json
@@ -2867,5 +2867,41 @@
"url": "<a href=\"url:\">url:</a>"
}
]
+ },
+ {
+ "name": "Test dictionary deinflection",
+ "results": [
+ {
+ "audio": "",
+ "clipboard-image": "",
+ "clipboard-text": "",
+ "cloze-body": "のたもうた",
+ "cloze-prefix": "cloze-prefix",
+ "cloze-suffix": "cloze-suffix",
+ "conjugation": "past",
+ "dictionary": "Test Dictionary 2",
+ "document-title": "title",
+ "expression": "のたまう",
+ "frequencies": "",
+ "furigana": "のたまう",
+ "furigana-plain": "のたまう",
+ "glossary": "<div style=\"text-align: left;\"><i>(v5, Test Dictionary 2)</i> notamau definition</div>",
+ "glossary-brief": "<div style=\"text-align: left;\">notamau definition</div>",
+ "glossary-no-dictionary": "<div style=\"text-align: left;\"><i>(v5)</i> notamau definition</div>",
+ "part-of-speech": "Godan verb",
+ "pitch-accents": "No pitch accent data",
+ "pitch-accent-graphs": "No pitch accent data",
+ "pitch-accent-positions": "No pitch accent data",
+ "phonetic-transcriptions": "",
+ "reading": "のたまう",
+ "screenshot": "",
+ "search-query": "fullQuery",
+ "selection-text": "",
+ "sentence": "cloze-prefixのたもうたcloze-suffix",
+ "sentence-furigana": "cloze-prefixのたもうたcloze-suffix",
+ "tags": "v5",
+ "url": "<a href=\"url:\">url:</a>"
+ }
+ ]
}
] \ No newline at end of file
diff --git a/test/data/database-test-cases.json b/test/data/database-test-cases.json
index 02fddd49..611903dd 100644
--- a/test/data/database-test-cases.json
+++ b/test/data/database-test-cases.json
@@ -27,7 +27,7 @@
"ipa": 1
},
"terms": {
- "total": 23
+ "total": 25
}
}
},
@@ -36,7 +36,7 @@
{
"kanji": 2,
"kanjiMeta": 6,
- "terms": 23,
+ "terms": 25,
"termMeta": 39,
"tagMeta": 15,
"media": 6
@@ -45,7 +45,7 @@
"total": {
"kanji": 2,
"kanjiMeta": 6,
- "terms": 23,
+ "terms": 25,
"termMeta": 39,
"tagMeta": 15,
"media": 6
diff --git a/test/data/dictionaries/valid-dictionary1/term_bank_1.json b/test/data/dictionaries/valid-dictionary1/term_bank_1.json
index ce4290bd..7f2af6dd 100644
--- a/test/data/dictionaries/valid-dictionary1/term_bank_1.json
+++ b/test/data/dictionaries/valid-dictionary1/term_bank_1.json
@@ -337,5 +337,7 @@
{"type": "structured-content", "content": "kouzou definition 3 (構造)"}
],
101, "P E1"
- ]
+ ],
+ ["のたまう", "のたまう", "v5", "v5", 1, ["notamau definition"], 15, ""],
+ ["のたもうた", "のたもうた", "", "", 1, [["のたまう", ["past"]]], 16, ""]
] \ No newline at end of file
diff --git a/test/data/translator-test-inputs.json b/test/data/translator-test-inputs.json
index 91cf0ab2..ce449c1e 100644
--- a/test/data/translator-test-inputs.json
+++ b/test/data/translator-test-inputs.json
@@ -35,7 +35,8 @@
"index": 0,
"priority": 0,
"allowSecondarySearches": false,
- "partsOfSpeechFilter": true
+ "partsOfSpeechFilter": true,
+ "useDeinflections": true
}
]
]
@@ -344,6 +345,13 @@
"mode": "split",
"text": "構造",
"options": "default"
+ },
+ {
+ "name": "Test dictionary deinflection",
+ "func": "findTerms",
+ "mode": "split",
+ "text": "のたもうた",
+ "options": "default"
}
]
} \ No newline at end of file
diff --git a/test/data/translator-test-results-note-data1.json b/test/data/translator-test-results-note-data1.json
index 1342a63f..c34842da 100644
--- a/test/data/translator-test-results-note-data1.json
+++ b/test/data/translator-test-results-note-data1.json
@@ -341,7 +341,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 1,
@@ -647,7 +652,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 2,
@@ -967,7 +977,12 @@
"source": "打つ",
"rawSource": "打つ",
"sourceTerm": "打つ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 3,
@@ -1273,7 +1288,12 @@
"source": "打つ",
"rawSource": "打つ",
"sourceTerm": "打つ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 3,
@@ -1579,7 +1599,12 @@
"source": "打つ",
"rawSource": "打つ",
"sourceTerm": "打つ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 3,
@@ -1885,7 +1910,12 @@
"source": "打つ",
"rawSource": "打つ",
"sourceTerm": "打つ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 3,
@@ -2191,7 +2221,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 1,
@@ -2497,7 +2532,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 2,
@@ -2817,7 +2857,12 @@
"source": "打ち込む",
"rawSource": "打ち込む",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 4,
@@ -3231,7 +3276,12 @@
"source": "打ち込む",
"rawSource": "打ち込む",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 4,
@@ -3645,7 +3695,12 @@
"source": "打ち込む",
"rawSource": "打ち込む",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 4,
@@ -4059,7 +4114,12 @@
"source": "打ち込む",
"rawSource": "打ち込む",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 4,
@@ -4473,8 +4533,13 @@
"source": "打ち",
"rawSource": "打ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -4781,8 +4846,13 @@
"source": "打ち",
"rawSource": "打ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -5089,8 +5159,13 @@
"source": "打ち",
"rawSource": "打ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -5397,8 +5472,13 @@
"source": "打ち",
"rawSource": "打ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -5705,7 +5785,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 1,
@@ -6011,7 +6096,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 2,
@@ -6331,7 +6421,12 @@
"source": "画像",
"rawSource": "画像",
"sourceTerm": "画像",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 5,
@@ -6485,7 +6580,12 @@
"source": "だ",
"rawSource": "だ",
"sourceTerm": "だ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 1,
@@ -6796,7 +6896,12 @@
"source": "ダース",
"rawSource": "ダース",
"sourceTerm": "ダース",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 2,
@@ -7116,7 +7221,12 @@
"source": "うつ",
"rawSource": "うつ",
"sourceTerm": "うつ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 3,
@@ -7422,7 +7532,12 @@
"source": "うつ",
"rawSource": "うつ",
"sourceTerm": "うつ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 3,
@@ -7733,7 +7848,12 @@
"source": "ぶつ",
"rawSource": "ぶつ",
"sourceTerm": "ぶつ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 3,
@@ -8039,7 +8159,12 @@
"source": "ぶつ",
"rawSource": "ぶつ",
"sourceTerm": "ぶつ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 3,
@@ -8350,7 +8475,12 @@
"source": "うちこむ",
"rawSource": "うちこむ",
"sourceTerm": "うちこむ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 4,
@@ -8764,7 +8894,12 @@
"source": "うちこむ",
"rawSource": "うちこむ",
"sourceTerm": "うちこむ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 4,
@@ -9178,8 +9313,13 @@
"source": "うち",
"rawSource": "うち",
"sourceTerm": "うつ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -9486,8 +9626,13 @@
"source": "うち",
"rawSource": "うち",
"sourceTerm": "うつ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -9799,7 +9944,12 @@
"source": "ぶちこむ",
"rawSource": "ぶちこむ",
"sourceTerm": "ぶちこむ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 4,
@@ -10213,7 +10363,12 @@
"source": "ぶちこむ",
"rawSource": "ぶちこむ",
"sourceTerm": "ぶちこむ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 4,
@@ -10627,8 +10782,13 @@
"source": "ぶち",
"rawSource": "ぶち",
"sourceTerm": "ぶつ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -10935,8 +11095,13 @@
"source": "ぶち",
"rawSource": "ぶち",
"sourceTerm": "ぶつ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -11248,7 +11413,12 @@
"source": "がぞう",
"rawSource": "がぞう",
"sourceTerm": "がぞう",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 5,
@@ -11413,7 +11583,12 @@
"source": "打ち込む",
"rawSource": "打ち込む",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"sequence": 4,
"dictionary": "Test Dictionary 2",
@@ -11850,7 +12025,12 @@
"source": "打ち込む",
"rawSource": "打ち込む",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"sequence": 4,
"dictionary": "Test Dictionary 2",
@@ -12287,8 +12467,13 @@
"source": "打ち",
"rawSource": "打ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"sequence": 3,
@@ -12626,8 +12811,13 @@
"source": "打ち",
"rawSource": "打ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"sequence": 3,
@@ -12965,7 +13155,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"sequence": 1,
"dictionary": "Test Dictionary 2",
@@ -13269,7 +13464,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"sequence": 2,
"dictionary": "Test Dictionary 2",
@@ -13586,7 +13786,12 @@
"type": "termMerged",
"source": "打ち込む",
"rawSource": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"sequence": 4,
"dictionary": "Test Dictionary 2",
@@ -14351,8 +14556,13 @@
"type": "termMerged",
"source": "打ち",
"rawSource": "打ち",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"sequence": 3,
@@ -14923,7 +15133,12 @@
"type": "termMerged",
"source": "打",
"rawSource": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"sequence": 1,
"dictionary": "Test Dictionary 2",
@@ -15220,7 +15435,12 @@
"type": "termMerged",
"source": "打",
"rawSource": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"sequence": 2,
"dictionary": "Test Dictionary 2",
@@ -15533,10 +15753,15 @@
"source": "打ち込んでいませんでした",
"rawSource": "打ち込んでいませんでした",
"sourceTerm": "打ち込む",
- "reasons": [
- "-te",
- "progressive or perfect",
- "polite past negative"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "-te",
+ "progressive or perfect",
+ "polite past negative"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -15951,10 +16176,15 @@
"source": "打ち込んでいませんでした",
"rawSource": "打ち込んでいませんでした",
"sourceTerm": "打ち込む",
- "reasons": [
- "-te",
- "progressive or perfect",
- "polite past negative"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "-te",
+ "progressive or perfect",
+ "polite past negative"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -16369,10 +16599,15 @@
"source": "打ち込んでいませんでした",
"rawSource": "打ち込んでいませんでした",
"sourceTerm": "打ち込む",
- "reasons": [
- "-te",
- "progressive or perfect",
- "polite past negative"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "-te",
+ "progressive or perfect",
+ "polite past negative"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -16787,10 +17022,15 @@
"source": "打ち込んでいませんでした",
"rawSource": "打ち込んでいませんでした",
"sourceTerm": "打ち込む",
- "reasons": [
- "-te",
- "progressive or perfect",
- "polite past negative"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "-te",
+ "progressive or perfect",
+ "polite past negative"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -17205,8 +17445,13 @@
"source": "打ち",
"rawSource": "打ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -17513,8 +17758,13 @@
"source": "打ち",
"rawSource": "打ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -17821,8 +18071,13 @@
"source": "打ち",
"rawSource": "打ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -18129,8 +18384,13 @@
"source": "打ち",
"rawSource": "打ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -18437,7 +18697,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 1,
@@ -18743,7 +19008,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 2,
@@ -19063,7 +19333,12 @@
"source": "打ち込む",
"rawSource": "打(う)ち込(こ)む",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 4,
@@ -19477,7 +19752,12 @@
"source": "打ち込む",
"rawSource": "打(う)ち込(こ)む",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 4,
@@ -19891,7 +20171,12 @@
"source": "打ち込む",
"rawSource": "打(う)ち込(こ)む",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 4,
@@ -20305,7 +20590,12 @@
"source": "打ち込む",
"rawSource": "打(う)ち込(こ)む",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 4,
@@ -20719,8 +21009,13 @@
"source": "打ち",
"rawSource": "打(う)ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -21027,8 +21322,13 @@
"source": "打ち",
"rawSource": "打(う)ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -21335,8 +21635,13 @@
"source": "打ち",
"rawSource": "打(う)ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -21643,8 +21948,13 @@
"source": "打ち",
"rawSource": "打(う)ち",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -21951,7 +22261,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 1,
@@ -22257,7 +22572,12 @@
"source": "打",
"rawSource": "打",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 2,
@@ -22577,7 +22897,12 @@
"source": "打ち込む",
"rawSource": "(打)(ち)(込)(む)",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 4,
@@ -22991,7 +23316,12 @@
"source": "打ち込む",
"rawSource": "(打)(ち)(込)(む)",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"isPrimary": true,
"sequence": 4,
@@ -23405,7 +23735,12 @@
"source": "打ち込む",
"rawSource": "(打)(ち)(込)(む)",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 4,
@@ -23819,7 +24154,12 @@
"source": "打ち込む",
"rawSource": "(打)(ち)(込)(む)",
"sourceTerm": "打ち込む",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 4,
@@ -24233,8 +24573,13 @@
"source": "打ち",
"rawSource": "(打)(ち)",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -24541,8 +24886,13 @@
"source": "打ち",
"rawSource": "(打)(ち)",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"isPrimary": true,
@@ -24849,8 +25199,13 @@
"source": "打ち",
"rawSource": "(打)(ち)",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -25157,8 +25512,13 @@
"source": "打ち",
"rawSource": "(打)(ち)",
"sourceTerm": "打つ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"isPrimary": true,
@@ -25465,7 +25825,12 @@
"source": "打",
"rawSource": "(打)",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 1,
@@ -25771,7 +26136,12 @@
"source": "打",
"rawSource": "(打)",
"sourceTerm": "打",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 2,
@@ -26091,8 +26461,13 @@
"source": "よみ",
"rawSource": "test",
"sourceTerm": "よむ",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 100,
"isPrimary": true,
@@ -26245,7 +26620,12 @@
"source": "つよみ",
"rawSource": "つtest",
"sourceTerm": "つよみ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 90,
"isPrimary": true,
"sequence": 7,
@@ -26397,8 +26777,13 @@
"source": "よみました",
"rawSource": "testました",
"sourceTerm": "よむ",
- "reasons": [
- "polite past"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "polite past"
+ ]
+ }
],
"score": 100,
"isPrimary": true,
@@ -26549,7 +26934,12 @@
"type": "termMerged",
"source": "うちこむ",
"rawSource": "うちこむ",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"sequence": 4,
"dictionary": "Test Dictionary 2",
@@ -27314,8 +27704,13 @@
"type": "termMerged",
"source": "うち",
"rawSource": "うち",
- "reasons": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"sequence": 3,
@@ -27893,7 +28288,12 @@
"source": "お手前",
"rawSource": "お手前",
"sourceTerm": "お手前",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 9,
@@ -28221,7 +28621,12 @@
"source": "番号",
"rawSource": "番号",
"sourceTerm": "番号",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 10,
@@ -28401,7 +28806,12 @@
"source": "中腰",
"rawSource": "中腰",
"sourceTerm": "中腰",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 11,
@@ -28581,7 +28991,12 @@
"source": "所業",
"rawSource": "所業",
"sourceTerm": "所業",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 12,
@@ -28761,7 +29176,12 @@
"source": "土木工事",
"rawSource": "土木工事",
"sourceTerm": "土木工事",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 13,
@@ -28941,7 +29361,12 @@
"source": "好き",
"rawSource": "好き",
"sourceTerm": "好き",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"isPrimary": true,
"sequence": 14,
@@ -29149,7 +29574,12 @@
"source": "構造",
"rawSource": "構造",
"sourceTerm": "構造",
- "reasons": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 35,
"isPrimary": true,
"sequence": 101,
@@ -29289,5 +29719,118 @@
"media": {}
}
]
+ },
+ {
+ "name": "Test dictionary deinflection",
+ "noteDataList": [
+ {
+ "marker": "{marker}",
+ "definition": {
+ "type": "term",
+ "id": 23,
+ "source": "のたもうた",
+ "rawSource": "のたもうた",
+ "sourceTerm": "のたまう",
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "both",
+ "inflectionRules": [
+ "past"
+ ]
+ }
+ ],
+ "score": 1,
+ "isPrimary": true,
+ "sequence": 15,
+ "dictionary": "Test Dictionary 2",
+ "dictionaryOrder": {
+ "index": 0,
+ "priority": 0
+ },
+ "dictionaryNames": [
+ "Test Dictionary 2"
+ ],
+ "expression": "のたまう",
+ "reading": "のたまう",
+ "expressions": [
+ {
+ "sourceTerm": "のたまう",
+ "expression": "のたまう",
+ "reading": "のたまう",
+ "termTags": [],
+ "frequencies": [],
+ "pitches": [],
+ "furiganaSegments": [
+ {
+ "text": "のたまう",
+ "furigana": ""
+ }
+ ],
+ "termFrequency": "normal",
+ "wordClasses": [
+ "v5"
+ ]
+ }
+ ],
+ "glossary": [
+ "notamau definition"
+ ],
+ "definitionTags": [
+ {
+ "name": "v5",
+ "category": "default",
+ "notes": "",
+ "order": 0,
+ "score": 0,
+ "dictionary": "Test Dictionary 2",
+ "redundant": false
+ }
+ ],
+ "termTags": [],
+ "frequencies": [],
+ "pitches": [],
+ "phoneticTranscriptions": [],
+ "sourceTermExactMatchCount": 1,
+ "url": "url:",
+ "cloze": {
+ "sentence": "",
+ "prefix": "",
+ "body": "",
+ "suffix": ""
+ },
+ "furiganaSegments": [
+ {
+ "text": "のたまう",
+ "furigana": ""
+ }
+ ]
+ },
+ "glossaryLayoutMode": "default",
+ "compactTags": false,
+ "group": false,
+ "merge": false,
+ "modeTermKanji": false,
+ "modeTermKana": false,
+ "modeKanji": false,
+ "compactGlossaries": false,
+ "uniqueExpressions": [
+ "のたまう"
+ ],
+ "uniqueReadings": [
+ "のたまう"
+ ],
+ "pitches": [],
+ "pitchCount": 0,
+ "phoneticTranscriptions": [],
+ "context": {
+ "query": "query",
+ "fullQuery": "fullQuery",
+ "document": {
+ "title": "title"
+ }
+ },
+ "media": {}
+ }
+ ]
}
] \ No newline at end of file
diff --git a/test/data/translator-test-results.json b/test/data/translator-test-results.json
index 50d97775..4a81c552 100644
--- a/test/data/translator-test-results.json
+++ b/test/data/translator-test-results.json
@@ -291,7 +291,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -454,7 +459,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -636,7 +646,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -801,7 +816,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -966,7 +986,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -1131,7 +1156,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -1296,7 +1326,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -1459,7 +1494,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -1641,7 +1681,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -1830,7 +1875,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -2019,7 +2069,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -2208,7 +2263,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -2397,8 +2457,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -2564,8 +2629,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -2731,8 +2801,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -2898,8 +2973,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -3065,7 +3145,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -3228,7 +3313,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -3410,7 +3500,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -3523,7 +3618,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -3692,7 +3792,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -3874,7 +3979,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -4039,7 +4149,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -4210,7 +4325,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -4375,7 +4495,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -4546,7 +4671,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -4735,7 +4865,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -4924,8 +5059,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -5091,8 +5231,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -5264,7 +5409,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -5453,7 +5603,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -5642,8 +5797,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -5809,8 +5969,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -5982,7 +6147,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -6105,7 +6275,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -6162,7 +6337,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -6219,7 +6399,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -6276,7 +6461,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -6333,8 +6523,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -6392,8 +6587,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -6451,8 +6651,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -6510,8 +6715,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -6569,7 +6779,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -6626,7 +6841,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -6689,7 +6909,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -6926,7 +7151,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -7163,8 +7393,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -7378,8 +7613,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -7593,7 +7833,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -7756,7 +8001,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -7938,7 +8188,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -8393,8 +8648,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -8803,7 +9063,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -8966,7 +9231,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -9148,10 +9418,15 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "-te",
- "progressive or perfect",
- "polite past negative"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "-te",
+ "progressive or perfect",
+ "polite past negative"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -9341,10 +9616,15 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "-te",
- "progressive or perfect",
- "polite past negative"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "-te",
+ "progressive or perfect",
+ "polite past negative"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -9534,10 +9814,15 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "-te",
- "progressive or perfect",
- "polite past negative"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "-te",
+ "progressive or perfect",
+ "polite past negative"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -9727,10 +10012,15 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "-te",
- "progressive or perfect",
- "polite past negative"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "-te",
+ "progressive or perfect",
+ "polite past negative"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -9920,8 +10210,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -10087,8 +10382,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -10254,8 +10554,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -10421,8 +10726,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -10588,7 +10898,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -10751,7 +11066,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -10933,7 +11253,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -11122,7 +11447,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -11311,7 +11641,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -11500,7 +11835,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -11689,8 +12029,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -11856,8 +12201,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -12023,8 +12373,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -12190,8 +12545,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -12357,7 +12717,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -12520,7 +12885,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -12702,7 +13072,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -12891,7 +13266,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -13080,7 +13460,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -13269,7 +13654,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -13458,8 +13848,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -13625,8 +14020,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -13792,8 +14192,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -13959,8 +14364,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 1,
"frequencyOrder": 0,
@@ -14126,7 +14536,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -14289,7 +14704,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -14471,8 +14891,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 100,
"frequencyOrder": 0,
@@ -14576,7 +15001,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 90,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -14679,8 +15109,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "polite past"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "polite past"
+ ]
+ }
],
"score": 100,
"frequencyOrder": 0,
@@ -14784,7 +15219,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 10,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -15239,8 +15679,13 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [
- "masu stem"
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": [
+ "masu stem"
+ ]
+ }
],
"score": 10,
"frequencyOrder": 0,
@@ -15655,7 +16100,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -15804,7 +16254,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -15899,7 +16354,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -15994,7 +16454,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -16089,7 +16554,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -16184,7 +16654,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 1,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -16296,7 +16771,12 @@
{
"type": "term",
"isPrimary": true,
- "inflections": [],
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "algorithm",
+ "inflectionRules": []
+ }
+ ],
"score": 35,
"frequencyOrder": 0,
"dictionaryIndex": 0,
@@ -16399,5 +16879,86 @@
"frequencies": []
}
]
+ },
+ {
+ "name": "Test dictionary deinflection",
+ "originalTextLength": 5,
+ "dictionaryEntries": [
+ {
+ "type": "term",
+ "isPrimary": true,
+ "inflectionRuleChainCandidates": [
+ {
+ "source": "both",
+ "inflectionRules": [
+ "past"
+ ]
+ }
+ ],
+ "score": 1,
+ "frequencyOrder": 0,
+ "dictionaryIndex": 0,
+ "dictionaryPriority": 0,
+ "sourceTermExactMatchCount": 1,
+ "maxTransformedTextLength": 5,
+ "headwords": [
+ {
+ "index": 0,
+ "term": "のたまう",
+ "reading": "のたまう",
+ "sources": [
+ {
+ "originalText": "のたもうた",
+ "transformedText": "のたもうた",
+ "deinflectedText": "のたまう",
+ "matchType": "exact",
+ "matchSource": "term",
+ "isPrimary": true
+ }
+ ],
+ "tags": [],
+ "wordClasses": [
+ "v5"
+ ]
+ }
+ ],
+ "definitions": [
+ {
+ "index": 0,
+ "headwordIndices": [
+ 0
+ ],
+ "dictionary": "Test Dictionary 2",
+ "dictionaryIndex": 0,
+ "dictionaryPriority": 0,
+ "id": 23,
+ "score": 1,
+ "frequencyOrder": 0,
+ "sequences": [
+ 15
+ ],
+ "isPrimary": true,
+ "tags": [
+ {
+ "name": "v5",
+ "category": "default",
+ "order": 0,
+ "score": 0,
+ "content": [],
+ "dictionaries": [
+ "Test Dictionary 2"
+ ],
+ "redundant": false
+ }
+ ],
+ "entries": [
+ "notamau definition"
+ ]
+ }
+ ],
+ "pronunciations": [],
+ "frequencies": []
+ }
+ ]
}
] \ No newline at end of file
diff --git a/test/options-util.test.js b/test/options-util.test.js
index a34cc93a..26ccdd14 100644
--- a/test/options-util.test.js
+++ b/test/options-util.test.js
@@ -426,7 +426,8 @@ function createProfileOptionsUpdatedTestData1() {
enabled: true,
allowSecondarySearches: false,
definitionsCollapsible: 'not-collapsible',
- partsOfSpeechFilter: true
+ partsOfSpeechFilter: true,
+ useDeinflections: true
}
],
parsing: {
@@ -603,7 +604,7 @@ function createOptionsUpdatedTestData1() {
}
],
profileCurrent: 0,
- version: 23,
+ version: 24,
global: {
database: {
prefixWildcardsSupported: false
diff --git a/types/ext/anki-templates.d.ts b/types/ext/anki-templates.d.ts
index 098873e6..7348b571 100644
--- a/types/ext/anki-templates.d.ts
+++ b/types/ext/anki-templates.d.ts
@@ -172,7 +172,7 @@ export type TermDictionaryEntry = {
source: string | null;
rawSource: string | null;
sourceTerm?: string | null;
- reasons: string[];
+ inflectionRuleChainCandidates: Dictionary.InflectionRuleChainCandidate[];
score: number;
isPrimary?: boolean;
readonly sequence: number;
diff --git a/types/ext/dictionary-data.d.ts b/types/ext/dictionary-data.d.ts
index 0e0edd5c..82e0f00d 100644
--- a/types/ext/dictionary-data.d.ts
+++ b/types/ext/dictionary-data.d.ts
@@ -90,6 +90,11 @@ export type KanjiV3 = [
];
export type TermGlossary = (
+ TermGlossaryContent |
+ TermGlossaryDeinflection
+);
+
+export type TermGlossaryContent = (
TermGlossaryString |
TermGlossaryText |
TermGlossaryImage |
@@ -100,6 +105,10 @@ export type TermGlossaryString = string;
export type TermGlossaryText = {type: 'text', text: string};
export type TermGlossaryImage = {type: 'image'} & TermImage;
export type TermGlossaryStructuredContent = {type: 'structured-content', content: StructuredContent.Content};
+export type TermGlossaryDeinflection = [
+ uninflected: string,
+ inflectionRuleChain: string[],
+];
export type TermImage = StructuredContent.ImageElementBase & {
// Compatibility properties
diff --git a/types/ext/dictionary.d.ts b/types/ext/dictionary.d.ts
index 7c348e7f..ed7769a9 100644
--- a/types/ext/dictionary.d.ts
+++ b/types/ext/dictionary.d.ts
@@ -208,9 +208,9 @@ export type TermDictionaryEntry = {
*/
isPrimary: boolean;
/**
- * A list of inflections that was applied to get the term.
+ * Ways that a looked-up word might be an inflected form of this term.
*/
- inflections: string[];
+ inflectionRuleChainCandidates: InflectionRuleChainCandidate[];
/**
* A score for the dictionary entry.
*/
@@ -253,6 +253,15 @@ export type TermDictionaryEntry = {
frequencies: TermFrequency[];
};
+export type InflectionRuleChainCandidate = {
+ source: InflectionSource;
+ inflectionRules: InflectionRuleChain;
+};
+
+export type InflectionRuleChain = string[];
+
+export type InflectionSource = 'algorithm' | 'dictionary' | 'both';
+
/**
* A term headword is a combination of a term, reading, and auxiliary information.
*/
@@ -337,7 +346,7 @@ export type TermDefinition = {
/**
* The definition entries.
*/
- entries: DictionaryData.TermGlossary[];
+ entries: DictionaryData.TermGlossaryContent[];
};
/**
diff --git a/types/ext/settings.d.ts b/types/ext/settings.d.ts
index b95691b2..a3d3e141 100644
--- a/types/ext/settings.d.ts
+++ b/types/ext/settings.d.ts
@@ -259,6 +259,7 @@ export type DictionaryOptions = {
allowSecondarySearches: boolean;
definitionsCollapsible: DictionaryDefinitionsCollapsible;
partsOfSpeechFilter: boolean;
+ useDeinflections: boolean;
};
export type ParsingOptions = {
diff --git a/types/ext/translation-internal.d.ts b/types/ext/translation-internal.d.ts
index 5845b45d..15456e41 100644
--- a/types/ext/translation-internal.d.ts
+++ b/types/ext/translation-internal.d.ts
@@ -16,6 +16,7 @@
*/
import type * as DictionaryDatabase from './dictionary-database';
+import type * as Dictionary from './dictionary';
import type * as Translation from './translation';
export type TextDeinflectionOptions = [
@@ -52,7 +53,7 @@ export enum DeinflectionRuleFlags {
export type Deinflection = {
term: string;
rules: DeinflectionRuleFlags;
- reasons: string[];
+ reasons: Dictionary.InflectionRuleChain;
};
export type DatabaseDeinflection = {
@@ -60,6 +61,6 @@ export type DatabaseDeinflection = {
transformedText: string;
deinflectedText: string;
rules: DeinflectionRuleFlags;
- reasons: string[];
+ inflectionRuleChainCandidates: Dictionary.InflectionRuleChainCandidate[];
databaseEntries: DictionaryDatabase.TermEntry[];
};
diff --git a/types/ext/translation.d.ts b/types/ext/translation.d.ts
index d597c006..db0cf02f 100644
--- a/types/ext/translation.d.ts
+++ b/types/ext/translation.d.ts
@@ -177,6 +177,10 @@ export type FindTermDictionary = {
* Whether this dictionary's part of speech rules should be used to filter results.
*/
partsOfSpeechFilter: boolean;
+ /**
+ * Whether to use the deinflections from this dictionary.
+ */
+ useDeinflections: boolean;
};
export type TermEnabledDictionaryMap = Map<string, FindTermDictionary>;