mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-07 03:22:17 -08:00
fix: prioritize SubMiner definitions in Yomitan
This commit is contained in:
@@ -656,7 +656,7 @@ test('getYomitanDictionaryInfo requests dictionary info via backend action', asy
|
|||||||
assert.match(scriptValue, /getDictionaryInfo/);
|
assert.match(scriptValue, /getDictionaryInfo/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dictionary settings helpers upsert and remove dictionary entries', async () => {
|
test('dictionary settings helpers upsert and remove dictionary entries without reordering', async () => {
|
||||||
const scripts: string[] = [];
|
const scripts: string[] = [];
|
||||||
const optionsFull = {
|
const optionsFull = {
|
||||||
profileCurrent: 0,
|
profileCurrent: 0,
|
||||||
|
|||||||
@@ -1676,7 +1676,7 @@ export async function upsertYomitanDictionarySettings(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dictionaries.unshift(createDefaultDictionarySettings(normalizedTitle, true));
|
dictionaries.push(createDefaultDictionarySettings(normalizedTitle, true));
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
93
src/yomitan-translator-sort.test.ts
Normal file
93
src/yomitan-translator-sort.test.ts
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
|
||||||
|
// @ts-expect-error Vendored Yomitan translator has no local TypeScript declarations.
|
||||||
|
import { Translator } from '../vendor/yomitan/js/language/translator.js';
|
||||||
|
|
||||||
|
type SortableTermEntry = {
|
||||||
|
matchPrimaryReading: boolean;
|
||||||
|
maxOriginalTextLength: number;
|
||||||
|
textProcessorRuleChainCandidates: unknown[];
|
||||||
|
inflectionRuleChainCandidates: unknown[];
|
||||||
|
sourceTermExactMatchCount: number;
|
||||||
|
frequencyOrder: number;
|
||||||
|
dictionaryIndex: number;
|
||||||
|
score: number;
|
||||||
|
dictionaryAlias: string;
|
||||||
|
headwords: Array<{ term: string }>;
|
||||||
|
definitions: Array<{ dictionary: string }>;
|
||||||
|
};
|
||||||
|
|
||||||
|
type SortableDefinition = {
|
||||||
|
dictionary: string;
|
||||||
|
dictionaryAlias: string;
|
||||||
|
frequencyOrder: number;
|
||||||
|
dictionaryIndex: number;
|
||||||
|
score: number;
|
||||||
|
headwordIndices: number[];
|
||||||
|
index: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
test('Translator prioritizes SubMiner term entries without changing dictionary index order', () => {
|
||||||
|
const translator = new Translator({});
|
||||||
|
const entries: SortableTermEntry[] = [
|
||||||
|
{
|
||||||
|
matchPrimaryReading: true,
|
||||||
|
maxOriginalTextLength: 4,
|
||||||
|
textProcessorRuleChainCandidates: [],
|
||||||
|
inflectionRuleChainCandidates: [],
|
||||||
|
sourceTermExactMatchCount: 1,
|
||||||
|
frequencyOrder: 0,
|
||||||
|
dictionaryIndex: 0,
|
||||||
|
score: 10,
|
||||||
|
dictionaryAlias: 'JMdict',
|
||||||
|
headwords: [{ term: 'アイリス' }],
|
||||||
|
definitions: [{ dictionary: 'JMdict' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
matchPrimaryReading: true,
|
||||||
|
maxOriginalTextLength: 4,
|
||||||
|
textProcessorRuleChainCandidates: [],
|
||||||
|
inflectionRuleChainCandidates: [],
|
||||||
|
sourceTermExactMatchCount: 1,
|
||||||
|
frequencyOrder: 99,
|
||||||
|
dictionaryIndex: 99,
|
||||||
|
score: 1,
|
||||||
|
dictionaryAlias: 'SubMiner Character Dictionary',
|
||||||
|
headwords: [{ term: 'アイリス' }],
|
||||||
|
definitions: [{ dictionary: 'SubMiner Character Dictionary' }],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
translator._sortTermDictionaryEntries(entries as unknown[]);
|
||||||
|
|
||||||
|
assert.equal(entries[0]?.dictionaryAlias, 'SubMiner Character Dictionary');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Translator prioritizes SubMiner definitions without changing dictionary index order', () => {
|
||||||
|
const translator = new Translator({});
|
||||||
|
const definitions: SortableDefinition[] = [
|
||||||
|
{
|
||||||
|
dictionary: 'JMdict',
|
||||||
|
dictionaryAlias: 'JMdict',
|
||||||
|
frequencyOrder: 0,
|
||||||
|
dictionaryIndex: 0,
|
||||||
|
score: 10,
|
||||||
|
headwordIndices: [0],
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dictionary: 'SubMiner Character Dictionary',
|
||||||
|
dictionaryAlias: 'SubMiner Character Dictionary',
|
||||||
|
frequencyOrder: 99,
|
||||||
|
dictionaryIndex: 99,
|
||||||
|
score: 1,
|
||||||
|
headwordIndices: [0],
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
translator._sortTermDictionaryEntryDefinitions(definitions as unknown[]);
|
||||||
|
|
||||||
|
assert.equal(definitions[0]?.dictionaryAlias, 'SubMiner Character Dictionary');
|
||||||
|
});
|
||||||
29
vendor/yomitan/js/language/translator.js
vendored
29
vendor/yomitan/js/language/translator.js
vendored
@@ -25,6 +25,8 @@ import {getAllLanguageReadingNormalizers, getAllLanguageTextProcessors} from './
|
|||||||
import {MultiLanguageTransformer} from './multi-language-transformer.js';
|
import {MultiLanguageTransformer} from './multi-language-transformer.js';
|
||||||
import {isCodePointChinese} from './zh/chinese.js';
|
import {isCodePointChinese} from './zh/chinese.js';
|
||||||
|
|
||||||
|
const SUBMINER_DICTIONARY_TITLE_PREFIX = 'SubMiner Character Dictionary';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class which finds term and kanji dictionary entries for text.
|
* Class which finds term and kanji dictionary entries for text.
|
||||||
*/
|
*/
|
||||||
@@ -1531,6 +1533,23 @@ export class Translator {
|
|||||||
return Array.isArray(value) ? value : (typeof value === 'number' ? [value] : []);
|
return Array.isArray(value) ? value : (typeof value === 'number' ? [value] : []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string|undefined} value
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
_isSubMinerDictionary(value) {
|
||||||
|
return typeof value === 'string' && value.startsWith(SUBMINER_DICTIONARY_TITLE_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string|undefined} dictionary
|
||||||
|
* @param {string|undefined} dictionaryAlias
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
_getSubMinerDictionarySortBoost(dictionary, dictionaryAlias) {
|
||||||
|
return (this._isSubMinerDictionary(dictionary) || this._isSubMinerDictionary(dictionaryAlias)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Kanji data
|
// Kanji data
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2162,6 +2181,10 @@ export class Translator {
|
|||||||
i = v2.sourceTermExactMatchCount - v1.sourceTermExactMatchCount;
|
i = v2.sourceTermExactMatchCount - v1.sourceTermExactMatchCount;
|
||||||
if (i !== 0) { return i; }
|
if (i !== 0) { return i; }
|
||||||
|
|
||||||
|
// Prefer SubMiner character dictionary entries without changing user dictionary order.
|
||||||
|
i = this._getSubMinerDictionarySortBoost(v2.definitions[0]?.dictionary, v2.dictionaryAlias) - this._getSubMinerDictionarySortBoost(v1.definitions[0]?.dictionary, v1.dictionaryAlias);
|
||||||
|
if (i !== 0) { return i; }
|
||||||
|
|
||||||
// Sort by frequency order
|
// Sort by frequency order
|
||||||
i = v1.frequencyOrder - v2.frequencyOrder;
|
i = v1.frequencyOrder - v2.frequencyOrder;
|
||||||
if (i !== 0) { return i; }
|
if (i !== 0) { return i; }
|
||||||
@@ -2205,8 +2228,12 @@ export class Translator {
|
|||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
const compareFunction = (v1, v2) => {
|
const compareFunction = (v1, v2) => {
|
||||||
|
// Prefer SubMiner character dictionary definitions without changing user dictionary order.
|
||||||
|
let i = this._getSubMinerDictionarySortBoost(v2.dictionary, v2.dictionaryAlias) - this._getSubMinerDictionarySortBoost(v1.dictionary, v1.dictionaryAlias);
|
||||||
|
if (i !== 0) { return i; }
|
||||||
|
|
||||||
// Sort by frequency order
|
// Sort by frequency order
|
||||||
let i = v1.frequencyOrder - v2.frequencyOrder;
|
i = v1.frequencyOrder - v2.frequencyOrder;
|
||||||
if (i !== 0) { return i; }
|
if (i !== 0) { return i; }
|
||||||
|
|
||||||
// Sort by dictionary order
|
// Sort by dictionary order
|
||||||
|
|||||||
Reference in New Issue
Block a user