mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-09-24 17:16:21 -07:00
fix(anki): regenerate sentence furigana when mined context changes
- Regenerate SentenceFurigana from the final sentence after timing-review expansion or stats-dashboard word mining - Add a Yomitan parseText-based generator with a 10s timeout and escaped, highlighted output - Clear stale furigana on failure so templates fall back to Sentence - Keep existing furigana formatting when the sentence is unchanged - Document the behavior in the anki-integration and immersion-tracking docs
This commit is contained in:
@@ -18,7 +18,6 @@ import {
|
||||
getStatsDirectMiningAudioFieldNames,
|
||||
getStatsWordMiningAudioFieldName,
|
||||
resolveStatsNoteFieldName,
|
||||
shouldUseStatsLapisKikuCardFields,
|
||||
statsMiningLogger,
|
||||
type StatsMiningRouteOptions,
|
||||
type StatsServerNoteInfo,
|
||||
@@ -229,19 +228,11 @@ export function registerStatsMiningRoutes(app: Hono, options?: StatsMiningRouteO
|
||||
|
||||
let imageBuffer = imageResult.status === 'fulfilled' ? imageResult.value : null;
|
||||
let noteInfo: StatsServerNoteInfo | null = null;
|
||||
if (
|
||||
audioBuffer ||
|
||||
(syncAnimatedImageToWordAudio && generateImage) ||
|
||||
shouldUseStatsLapisKikuCardFields(ankiConfig)
|
||||
) {
|
||||
try {
|
||||
const noteInfoResult = (await client.notesInfo([noteId])) as StatsServerNoteInfo[];
|
||||
noteInfo = noteInfoResult[0] ?? null;
|
||||
} catch (err) {
|
||||
if (syncAnimatedImageToWordAudio && generateImage) {
|
||||
errors.push(`image: ${(err as Error).message}`);
|
||||
}
|
||||
}
|
||||
try {
|
||||
const noteInfoResult = (await client.notesInfo([noteId])) as StatsServerNoteInfo[];
|
||||
noteInfo = noteInfoResult[0] ?? null;
|
||||
} catch (error) {
|
||||
errors.push(`note fields: ${error instanceof Error ? error.message : String(error)}`);
|
||||
}
|
||||
if (syncAnimatedImageToWordAudio && generateImage) {
|
||||
try {
|
||||
@@ -273,6 +264,24 @@ export function registerStatsMiningRoutes(app: Hono, options?: StatsMiningRouteO
|
||||
const imageFieldName = ankiConfig.fields?.image ?? 'Picture';
|
||||
|
||||
mediaFields[sentenceFieldName] = highlightedSentence;
|
||||
const furiganaFieldName = noteInfo
|
||||
? resolveStatsNoteFieldName(noteInfo, 'SentenceFurigana')
|
||||
: null;
|
||||
if (furiganaFieldName) {
|
||||
let furigana: string | null = null;
|
||||
try {
|
||||
furigana =
|
||||
(await options?.generateSentenceFurigana?.(
|
||||
sentence,
|
||||
ankiConfig.behavior?.highlightWord === false ? undefined : word,
|
||||
)) ?? null;
|
||||
} catch (error) {
|
||||
statsMiningLogger.warn('Failed to generate sentence furigana:', error);
|
||||
}
|
||||
mediaFields[furiganaFieldName] = furigana ?? '';
|
||||
if (furigana === null)
|
||||
errors.push('furigana: unavailable; using the full sentence without readings');
|
||||
}
|
||||
applyStatsWordCardFields(mediaFields, noteInfo, ankiConfig);
|
||||
|
||||
if (audioBuffer) {
|
||||
|
||||
Reference in New Issue
Block a user