mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-08-04 19:21:33 -07:00
fix(character-dictionary): drop single-letter mob name disambiguators
- AniList mob names like 女子A/"Joshi A" romanize their trailing disambiguator letter into a single kana term (A → ア) that collides with common interjections (あ〜); filter these out unless kanji - bump CHARACTER_DICTIONARY_FORMAT_VERSION to 20 to invalidate cached dictionaries built with the old term set - add tests covering the dropped disambiguator and a kept single-kanji name part
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
export const ANILIST_GRAPHQL_URL = 'https://graphql.anilist.co';
|
||||
export const ANILIST_REQUEST_DELAY_MS = 2000;
|
||||
export const CHARACTER_IMAGE_DOWNLOAD_DELAY_MS = 250;
|
||||
export const CHARACTER_DICTIONARY_FORMAT_VERSION = 19;
|
||||
export const CHARACTER_DICTIONARY_FORMAT_VERSION = 20;
|
||||
export const CHARACTER_DICTIONARY_MERGED_TITLE = 'SubMiner Character Dictionary';
|
||||
|
||||
export const HONORIFIC_SUFFIXES = [
|
||||
|
||||
@@ -36,3 +36,35 @@ test('buildNameTerms adds surname honorifics from Japanese localized aliases', (
|
||||
assert.ok(terms.includes('馬渕さん'));
|
||||
assert.ok(!terms.includes('송치'));
|
||||
});
|
||||
|
||||
test('buildNameTerms drops the disambiguator letter of a mob character name', () => {
|
||||
const terms = buildNameTerms(
|
||||
characterRecord({
|
||||
firstNameHint: '',
|
||||
lastNameHint: '',
|
||||
fullName: 'Joshi A',
|
||||
nativeName: '女子A',
|
||||
}),
|
||||
);
|
||||
|
||||
// ア would match every あ〜 in the subtitles; the letter is a disambiguator
|
||||
// (Girl A / Girl B), not a name.
|
||||
assert.ok(!terms.includes('ア'));
|
||||
assert.ok(!terms.includes('アさん'));
|
||||
assert.ok(terms.includes('女子A'));
|
||||
assert.ok(terms.includes('ジョシア'));
|
||||
});
|
||||
|
||||
test('buildNameTerms keeps a single-kanji name part', () => {
|
||||
const terms = buildNameTerms(
|
||||
characterRecord({
|
||||
firstNameHint: 'Sora',
|
||||
lastNameHint: 'Yamada',
|
||||
fullName: 'Sora Yamada',
|
||||
nativeName: '山田 空',
|
||||
}),
|
||||
);
|
||||
|
||||
assert.ok(terms.includes('山田'));
|
||||
assert.ok(terms.includes('空'));
|
||||
});
|
||||
|
||||
@@ -42,6 +42,15 @@ export function expandRawNameVariants(rawName: string): string[] {
|
||||
return [...variants];
|
||||
}
|
||||
|
||||
// AniList disambiguates unnamed mob characters with a trailing letter (女子A /
|
||||
// "Joshi A"), and a single letter romanizes into a single-kana alias (A → ア)
|
||||
// that collides with interjections (あ〜 matching ア). A one-character form is
|
||||
// only a real lookup target when it is kanji, so every other single-character
|
||||
// form is dropped before it can become a term.
|
||||
function isUsableNameTerm(name: string): boolean {
|
||||
return [...name].length > 1 || containsKanji(name);
|
||||
}
|
||||
|
||||
export function isJapaneseNameSplitCandidate(name: string): boolean {
|
||||
const compact = name.replace(/[\s\u3000・・·•]/g, '');
|
||||
return (
|
||||
@@ -97,8 +106,11 @@ export function buildNameTerms(
|
||||
|
||||
const split = name.split(/[\s\u3000]+/).filter((part) => part.trim().length > 0);
|
||||
if (split.length === 2) {
|
||||
target.add(split[0]!);
|
||||
target.add(split[1]!);
|
||||
for (const part of split) {
|
||||
if (isUsableNameTerm(part)) {
|
||||
target.add(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const splitByMiddleDot = name
|
||||
@@ -107,7 +119,9 @@ export function buildNameTerms(
|
||||
.filter((part) => part.length > 0);
|
||||
if (splitByMiddleDot.length >= 2) {
|
||||
for (const part of splitByMiddleDot) {
|
||||
target.add(part);
|
||||
if (isUsableNameTerm(part)) {
|
||||
target.add(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +150,7 @@ export function buildNameTerms(
|
||||
|
||||
const withHonorifics = new Set<string>();
|
||||
for (const entry of base) {
|
||||
if (!isUsableNameTerm(entry)) continue;
|
||||
withHonorifics.add(entry);
|
||||
for (const suffix of HONORIFIC_SUFFIXES) {
|
||||
withHonorifics.add(`${entry}${suffix.term}`);
|
||||
|
||||
Reference in New Issue
Block a user