From 0129e03c0f4fb931da0a57b8093cd1ea728135a7 Mon Sep 17 00:00:00 2001 From: sudacode Date: Wed, 28 Oct 2026 22:47:54 -0700 Subject: [PATCH] fix(anki): default fields.audio to SentenceAudio - Generated sentence audio no longer overwrites Yomitan's ExpressionAudio on default configs - fields.wordAudio still defaults to ExpressionAudio - Regenerate config.example.jsonc and update the Anki and configuration docs - Add changelog fragment --- changes/anki-sentence-audio-default.md | 4 ++++ config.example.jsonc | 2 +- docs-site/anki-integration.md | 2 +- docs-site/configuration.md | 18 +++++++++--------- docs-site/public/config.example.jsonc | 2 +- src/anki-integration.test.ts | 6 +++--- .../definitions/defaults-integrations.ts | 2 +- 7 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 changes/anki-sentence-audio-default.md diff --git a/changes/anki-sentence-audio-default.md b/changes/anki-sentence-audio-default.md new file mode 100644 index 00000000..a893407d --- /dev/null +++ b/changes/anki-sentence-audio-default.md @@ -0,0 +1,4 @@ +type: fixed +area: anki + +- `ankiConnect.fields.audio` now defaults to `SentenceAudio` instead of `ExpressionAudio`, so generated sentence audio no longer overwrites Yomitan's word audio on default configs. `fields.wordAudio` still defaults to `ExpressionAudio`. If you relied on the old default, set `fields.audio` to `ExpressionAudio` explicitly. diff --git a/config.example.jsonc b/config.example.jsonc index e895f90d..1dba331f 100644 --- a/config.example.jsonc +++ b/config.example.jsonc @@ -578,7 +578,7 @@ "deck": "", // Restrict duplicate detection and card enrichment to this Anki deck. Leave empty to use the Yomitan mining deck when available. "fields": { "word": "Expression", // Card field for the mined word or expression text. - "audio": "ExpressionAudio", // Card field that receives generated sentence audio. + "audio": "SentenceAudio", // Card field that receives generated sentence audio. "wordAudio": "ExpressionAudio", // Existing word-audio field read to time the frozen first frame of animated images. This mapping is only used for synchronization. "image": "Picture", // Card field that receives the captured screenshot or animated image. "sentence": "Sentence", // Card field that receives the source sentence text. diff --git a/docs-site/anki-integration.md b/docs-site/anki-integration.md index 23a04cbf..0b71127b 100644 --- a/docs-site/anki-integration.md +++ b/docs-site/anki-integration.md @@ -103,7 +103,7 @@ Field names are matched case-insensitively. A mapped field that is missing from Hachidori prepares downloadable word audio before it saves a note through the proxy, so the animated image delay works on the first mine. Set a downloadable pronunciation source in Hachidori's Audio settings. Browser speech cannot be saved to Anki. Without word audio, Hachidori shows a warning and the card gets no word-audio hold. -`fields.audio` gets sentence audio, not word audio. Yomitan writes its own dictionary audio into your note, so point `fields.audio` at a separate field such as `SentenceAudio`. The default, `ExpressionAudio`, is the field many note types use for Yomitan's word audio, so leaving it would overwrite that audio. +`fields.audio` gets sentence audio, not word audio. Yomitan writes its own dictionary audio into your note (often `ExpressionAudio`), so keep `fields.audio` pointed at a separate field such as the default `SentenceAudio`. Pointing it at Yomitan's word-audio field would overwrite that audio. `ankiConnect.tags` adds tags to every mined or updated card. Set it to `[]` to add none. diff --git a/docs-site/configuration.md b/docs-site/configuration.md index 3daf5c51..84be8109 100644 --- a/docs-site/configuration.md +++ b/docs-site/configuration.md @@ -329,15 +329,15 @@ Creates and updates Anki cards with sentence, audio, and screenshot. Needs the [ **Fields** -| Key | Default | What it does | -| ------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -| `ankiConnect.fields.word` | `"Expression"` | Word field | -| `ankiConnect.fields.audio` | `"ExpressionAudio"` | Field that receives sentence audio. Set a separate field such as `SentenceAudio` so it does not overwrite Yomitan's word audio | -| `ankiConnect.fields.wordAudio` | `"ExpressionAudio"` | Existing word-audio field, read only to time animated images | -| `ankiConnect.fields.image` | `"Picture"` | Screenshot field | -| `ankiConnect.fields.sentence` | `"Sentence"` | Sentence field | -| `ankiConnect.fields.miscInfo` | `"MiscInfo"` | Metadata field. `null` disables | -| `ankiConnect.metadata.pattern` | `"[SubMiner] %f (%t)"` | MiscInfo template: `%f` filename, `%F` filename with extension, `%t` time, `%T` time with ms, `
` newline | +| Key | Default | What it does | +| ------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| `ankiConnect.fields.word` | `"Expression"` | Word field | +| `ankiConnect.fields.audio` | `"SentenceAudio"` | Field that receives sentence audio. Keep it separate from Yomitan's word-audio field so it does not overwrite that audio | +| `ankiConnect.fields.wordAudio` | `"ExpressionAudio"` | Existing word-audio field, read only to time animated images | +| `ankiConnect.fields.image` | `"Picture"` | Screenshot field | +| `ankiConnect.fields.sentence` | `"Sentence"` | Sentence field | +| `ankiConnect.fields.miscInfo` | `"MiscInfo"` | Metadata field. `null` disables | +| `ankiConnect.metadata.pattern` | `"[SubMiner] %f (%t)"` | MiscInfo template: `%f` filename, `%F` filename with extension, `%t` time, `%T` time with ms, `
` newline | **Media** diff --git a/docs-site/public/config.example.jsonc b/docs-site/public/config.example.jsonc index e895f90d..1dba331f 100644 --- a/docs-site/public/config.example.jsonc +++ b/docs-site/public/config.example.jsonc @@ -578,7 +578,7 @@ "deck": "", // Restrict duplicate detection and card enrichment to this Anki deck. Leave empty to use the Yomitan mining deck when available. "fields": { "word": "Expression", // Card field for the mined word or expression text. - "audio": "ExpressionAudio", // Card field that receives generated sentence audio. + "audio": "SentenceAudio", // Card field that receives generated sentence audio. "wordAudio": "ExpressionAudio", // Existing word-audio field read to time the frozen first frame of animated images. This mapping is only used for synchronization. "image": "Picture", // Card field that receives the captured screenshot or animated image. "sentence": "Sentence", // Card field that receives the source sentence text. diff --git a/src/anki-integration.test.ts b/src/anki-integration.test.ts index 11ac03c6..90a118b6 100644 --- a/src/anki-integration.test.ts +++ b/src/anki-integration.test.ts @@ -637,7 +637,7 @@ test('AnkiIntegration queues YouTube media updates against recovered source URLs noteId: 404, noteInfo: { noteId: 404, - fields: { ExpressionAudio: { value: '' }, Picture: { value: '' } }, + fields: { SentenceAudio: { value: '' }, Picture: { value: '' } }, }, label: 'resolved source', }); @@ -648,8 +648,8 @@ test('AnkiIntegration queues YouTube media updates against recovered source URLs assert.equal(queued, true); assert.equal(updatedNotes.length, 1); assert.equal(updatedNotes[0]?.noteId, 404); - assert.match(updatedNotes[0]?.fields.ExpressionAudio ?? '', /^\[sound:audio_/); - assert.equal(updatedNotes[0]?.fields.SentenceAudio, undefined); + assert.match(updatedNotes[0]?.fields.SentenceAudio ?? '', /^\[sound:audio_/); + assert.equal(updatedNotes[0]?.fields.ExpressionAudio, undefined); assert.match(updatedNotes[0]?.fields.Picture ?? '', /^