aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-07-09 17:48:27 -0400
committerGitHub <noreply@github.com>2021-07-09 17:48:27 -0400
commit8c68fa4d9435b562ffe23df92a2b7b620a0ed78e (patch)
tree8c622fe11063b3f9694033f10e47b2ac05badccc
parent0d167095479822adf1ed8918e3d1a349b3a53377 (diff)
Anki text furigana parsing and {sentence-furigana} marker (#1814)
* Add support for textFurigana media * Add readingMode parameter * Implement readingMode * Add {sentence-furigana} marker * Fallback to sentence if furigana isn't available * Update test data
-rw-r--r--README.md2
-rw-r--r--ext/data/templates/anki-field-templates-upgrade-v13.handlebars10
-rw-r--r--ext/data/templates/default-anki-field-templates.handlebars10
-rw-r--r--ext/js/data/anki-note-builder.js66
-rw-r--r--ext/js/data/options-util.js1
-rw-r--r--ext/js/display/display-anki.js14
-rw-r--r--ext/js/display/display.js2
-rw-r--r--ext/js/pages/settings/anki-controller.js2
-rw-r--r--ext/js/pages/settings/anki-templates-controller.js3
-rw-r--r--ext/js/templates/template-renderer-media-provider.js34
-rw-r--r--ext/settings.html4
-rw-r--r--test/data/anki-note-builder-test-results.json81
-rw-r--r--test/test-anki-note-builder.js15
13 files changed, 217 insertions, 27 deletions
diff --git a/README.md b/README.md
index de6d248d..7d9c5d44 100644
--- a/README.md
+++ b/README.md
@@ -179,6 +179,7 @@ Flashcard fields can be configured with the following steps:
`{search-query}` | The full search query shown on the search page.
`{selection-text}` | The selected text on the search page or popup.
`{sentence}` | Sentence, quote, or phrase that the term appears in from the source content.
+ `{sentence-furigana}` | Sentence, quote, or phrase that the term appears in from the source content, with furigana added.
`{tags}` | Grammar and usage tags providing information about the term (unavailable in *grouped* mode).
`{url}` | Address of the web page in which the term appeared in.
@@ -202,6 +203,7 @@ Flashcard fields can be configured with the following steps:
`{search-query}` | The full search query shown on the search page.
`{selection-text}` | The selected text on the search page or popup.
`{sentence}` | Sentence, quote, or phrase that the character appears in from the source content.
+ `{sentence-furigana}` | Sentence, quote, or phrase that the character appears in from the source content, with furigana added.
`{stroke-count}` | Number of strokes that the kanji character has.
`{url}` | Address of the web page in which the kanji appeared in.
diff --git a/ext/data/templates/anki-field-templates-upgrade-v13.handlebars b/ext/data/templates/anki-field-templates-upgrade-v13.handlebars
index 78820b95..25007030 100644
--- a/ext/data/templates/anki-field-templates-upgrade-v13.handlebars
+++ b/ext/data/templates/anki-field-templates-upgrade-v13.handlebars
@@ -2,6 +2,16 @@
{{~#if (hasMedia "selectionText")}}{{#getMedia "selectionText" format="text"}}{{/getMedia}}{{/if~}}
{{/inline}}
+{{#*inline "sentence-furigana"}}
+ {{~#if definition.cloze~}}
+ {{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}}
+ {{#getMedia "textFurigana" definition.cloze.sentence format="html"}}{{/getMedia}}
+ {{~else~}}
+ {{definition.cloze.sentence}}
+ {{~/if~}}
+ {{~/if~}}
+{{/inline}}
+
{{<<<<<<<}}
{{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{/each}}
{{=======}}
diff --git a/ext/data/templates/default-anki-field-templates.handlebars b/ext/data/templates/default-anki-field-templates.handlebars
index c9ee2833..cdbec87d 100644
--- a/ext/data/templates/default-anki-field-templates.handlebars
+++ b/ext/data/templates/default-anki-field-templates.handlebars
@@ -382,4 +382,14 @@
{{~#if (hasMedia "selectionText")}}{{#getMedia "selectionText" format="text"}}{{/getMedia}}{{/if~}}
{{/inline}}
+{{#*inline "sentence-furigana"}}
+ {{~#if definition.cloze~}}
+ {{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}}
+ {{#getMedia "textFurigana" definition.cloze.sentence format="html"}}{{/getMedia}}
+ {{~else~}}
+ {{definition.cloze.sentence}}
+ {{~/if~}}
+ {{~/if~}}
+{{/inline}}
+
{{~> (lookup . "marker") ~}}
diff --git a/ext/js/data/anki-note-builder.js b/ext/js/data/anki-note-builder.js
index 23dd648b..02aa7969 100644
--- a/ext/js/data/anki-note-builder.js
+++ b/ext/js/data/anki-note-builder.js
@@ -21,7 +21,8 @@
*/
class AnkiNoteBuilder {
- constructor() {
+ constructor({japaneseUtil}) {
+ this._japaneseUtil = japaneseUtil;
this._markerPattern = AnkiUtil.cloneFieldMarkerPattern(true);
this._templateRenderer = new TemplateRendererProxy();
this._batchedRequests = [];
@@ -284,6 +285,7 @@ class AnkiNoteBuilder {
let injectClipboardImage = false;
let injectClipboardText = false;
let injectSelectionText = false;
+ const textFuriganaDetails = [];
const dictionaryMediaDetails = [];
for (const requirement of requirements) {
const {type} = requirement;
@@ -293,6 +295,12 @@ class AnkiNoteBuilder {
case 'clipboardImage': injectClipboardImage = true; break;
case 'clipboardText': injectClipboardText = true; break;
case 'selectionText': injectSelectionText = true; break;
+ case 'textFurigana':
+ {
+ const {text, readingMode} = requirement;
+ textFuriganaDetails.push({text, readingMode});
+ }
+ break;
case 'dictionaryMedia':
{
const {dictionary, path} = requirement;
@@ -323,6 +331,14 @@ class AnkiNoteBuilder {
}
}
}
+ let textFuriganaPromise = null;
+ if (textFuriganaDetails.length > 0) {
+ const textParsingOptions = mediaOptions.textParsing;
+ if (typeof textParsingOptions === 'object' && textParsingOptions !== null) {
+ const {optionsContext, scanLength} = textParsingOptions;
+ textFuriganaPromise = this._getTextFurigana(textFuriganaDetails, optionsContext, scanLength);
+ }
+ }
// Inject media
const selectionText = injectSelectionText ? this._getSelectionText() : null;
@@ -335,6 +351,7 @@ class AnkiNoteBuilder {
dictionaryMediaDetails
);
const {audioFileName, screenshotFileName, clipboardImageFileName, clipboardText, dictionaryMedia: dictionaryMediaArray, errors} = injectedMedia;
+ const textFurigana = textFuriganaPromise !== null ? await textFuriganaPromise : [];
// Format results
const dictionaryMedia = {};
@@ -353,6 +370,7 @@ class AnkiNoteBuilder {
clipboardImage: (typeof clipboardImageFileName === 'string' ? {fileName: clipboardImageFileName} : null),
clipboardText: (typeof clipboardText === 'string' ? {text: clipboardText} : null),
selectionText: (typeof selectionText === 'string' ? {text: selectionText} : null),
+ textFurigana,
dictionaryMedia
};
return {media, errors};
@@ -361,4 +379,50 @@ class AnkiNoteBuilder {
_getSelectionText() {
return document.getSelection().toString();
}
+
+ async _getTextFurigana(entries, optionsContext, scanLength) {
+ const results = [];
+ for (const {text, readingMode} of entries) {
+ const parseResults = await yomichan.api.parseText(text, optionsContext, scanLength, true, false);
+ let data = null;
+ for (const {source, content} of parseResults) {
+ if (source !== 'scanning-parser') { continue; }
+ data = content;
+ break;
+ }
+ if (data !== null) {
+ const html = this._createFuriganaHtml(data, readingMode);
+ results.push({text, readingMode, details: {html}});
+ }
+ }
+ return results;
+ }
+
+ _createFuriganaHtml(data, readingMode) {
+ let result = '';
+ for (const term of data) {
+ result += '<span class="term">';
+ for (const {text, reading} of term) {
+ if (reading.length > 0) {
+ const reading2 = this._convertReading(reading, readingMode);
+ result += `<ruby>${text}<rt>${reading2}</rt></ruby>`;
+ } else {
+ result += text;
+ }
+ }
+ result += '</span>';
+ }
+ return result;
+ }
+
+ _convertReading(reading, readingMode) {
+ switch (readingMode) {
+ case 'hiragana':
+ return this._japaneseUtil.convertKatakanaToHiragana(reading);
+ case 'katakana':
+ return this._japaneseUtil.convertHiraganaToKatakana(reading);
+ default:
+ return reading;
+ }
+ }
}
diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js
index 3d36fc2e..36630e2f 100644
--- a/ext/js/data/options-util.js
+++ b/ext/js/data/options-util.js
@@ -855,6 +855,7 @@ class OptionsUtil {
// Handlebars templates updated to use formatGlossary.
// Handlebars templates updated to use new media format.
// Added {selection-text} field marker.
+ // Added {sentence-furigana} field marker.
await this._applyAnkiFieldTemplatesPatch(options, '/data/templates/anki-field-templates-upgrade-v13.handlebars');
return options;
}
diff --git a/ext/js/display/display-anki.js b/ext/js/display/display-anki.js
index 114a9d13..235149ad 100644
--- a/ext/js/display/display-anki.js
+++ b/ext/js/display/display-anki.js
@@ -22,11 +22,11 @@
*/
class DisplayAnki {
- constructor(display) {
+ constructor(display, japaneseUtil) {
this._display = display;
this._ankiFieldTemplates = null;
this._ankiFieldTemplatesDefault = null;
- this._ankiNoteBuilder = new AnkiNoteBuilder();
+ this._ankiNoteBuilder = new AnkiNoteBuilder({japaneseUtil});
this._ankiNoteNotification = null;
this._ankiNoteNotificationEventListeners = null;
this._ankiTagNotification = null;
@@ -44,6 +44,7 @@ class DisplayAnki {
this._duplicateScope = 'collection';
this._screenshotFormat = 'png';
this._screenshotQuality = 100;
+ this._scanLength = 10;
this._noteTags = [];
this._modeOptions = new Map();
this._dictionaryEntryTypeModeMap = new Map([
@@ -141,7 +142,8 @@ class DisplayAnki {
_onOptionsUpdated({options}) {
const {
general: {resultOutputMode, glossaryLayoutMode, compactTags},
- anki: {tags, duplicateScope, suspendNewCards, checkForDuplicates, displayTags, kanji, terms, screenshot: {format, quality}}
+ anki: {tags, duplicateScope, suspendNewCards, checkForDuplicates, displayTags, kanji, terms, screenshot: {format, quality}},
+ scanning: {length: scanLength}
} = options;
this._checkForDuplicates = checkForDuplicates;
@@ -153,6 +155,7 @@ class DisplayAnki {
this._duplicateScope = duplicateScope;
this._screenshotFormat = format;
this._screenshotQuality = quality;
+ this._scanLength = scanLength;
this._noteTags = [...tags];
this._modeOptions.clear();
this._modeOptions.set('kanji', kanji);
@@ -526,6 +529,7 @@ class DisplayAnki {
const contentOrigin = this._display.getContentOrigin();
const details = this._ankiNoteBuilder.getDictionaryEntryDetailsForNote(dictionaryEntry);
const audioDetails = (details.type === 'term' ? this._display.getAnkiNoteMediaAudioDetails(details.term, details.reading) : null);
+ const optionsContext = this._display.getOptionsContext();
const {note, errors, requirements: outputRequirements} = await this._ankiNoteBuilder.createNote({
dictionaryEntry,
@@ -547,6 +551,10 @@ class DisplayAnki {
format: this._screenshotFormat,
quality: this._screenshotQuality,
contentOrigin
+ },
+ textParsing: {
+ optionsContext,
+ scanLength: this._scanLength
}
},
requirements
diff --git a/ext/js/display/display.js b/ext/js/display/display.js
index d79cc7e2..12486a72 100644
--- a/ext/js/display/display.js
+++ b/ext/js/display/display.js
@@ -110,7 +110,7 @@ class Display extends EventDispatcher {
this._queryPostProcessor = null;
this._optionToggleHotkeyHandler = new OptionToggleHotkeyHandler(this);
this._elementOverflowController = new ElementOverflowController();
- this._displayAnki = new DisplayAnki(this);
+ this._displayAnki = new DisplayAnki(this, japaneseUtil);
this._hotkeyHandler.registerActions([
['close', () => { this._onHotkeyClose(); }],
diff --git a/ext/js/pages/settings/anki-controller.js b/ext/js/pages/settings/anki-controller.js
index b98de1b6..c0f7f626 100644
--- a/ext/js/pages/settings/anki-controller.js
+++ b/ext/js/pages/settings/anki-controller.js
@@ -104,6 +104,7 @@ class AnkiController {
'search-query',
'selection-text',
'sentence',
+ 'sentence-furigana',
'tags',
'url'
];
@@ -123,6 +124,7 @@ class AnkiController {
'screenshot',
'search-query',
'selection-text',
+ 'sentence-furigana',
'sentence',
'stroke-count',
'tags',
diff --git a/ext/js/pages/settings/anki-templates-controller.js b/ext/js/pages/settings/anki-templates-controller.js
index aa565bad..ad2790ca 100644
--- a/ext/js/pages/settings/anki-templates-controller.js
+++ b/ext/js/pages/settings/anki-templates-controller.js
@@ -17,6 +17,7 @@
/* global
* AnkiNoteBuilder
+ * JapaneseUtil
*/
class AnkiTemplatesController {
@@ -32,7 +33,7 @@ class AnkiTemplatesController {
this._renderFieldInput = null;
this._renderResult = null;
this._fieldTemplateResetModal = null;
- this._ankiNoteBuilder = new AnkiNoteBuilder();
+ this._ankiNoteBuilder = new AnkiNoteBuilder({japaneseUtil: new JapaneseUtil(null)});
}
async prepare() {
diff --git a/ext/js/templates/template-renderer-media-provider.js b/ext/js/templates/template-renderer-media-provider.js
index 4fd40c67..604b5331 100644
--- a/ext/js/templates/template-renderer-media-provider.js
+++ b/ext/js/templates/template-renderer-media-provider.js
@@ -54,21 +54,7 @@ class TemplateRendererMediaProvider {
}
_getFormattedValue(data, format) {
- switch (format) {
- case 'fileName':
- {
- const {fileName} = data;
- if (typeof fileName === 'string') { return fileName; }
- }
- break;
- case 'text':
- {
- const {text} = data;
- if (typeof text === 'string') { return text; }
- }
- break;
- }
- return null;
+ return Object.prototype.hasOwnProperty.call(data, format) ? data[format] : null;
}
_getMediaData(media, args, namedArgs) {
@@ -79,6 +65,7 @@ class TemplateRendererMediaProvider {
case 'clipboardImage': return this._getSimpleMediaData(media, 'clipboardImage');
case 'clipboardText': return this._getSimpleMediaData(media, 'clipboardText');
case 'selectionText': return this._getSimpleMediaData(media, 'selectionText');
+ case 'textFurigana': return this._getTextFurigana(media, args[1], namedArgs);
case 'dictionaryMedia': return this._getDictionaryMedia(media, args[1], namedArgs);
default: return null;
}
@@ -114,4 +101,21 @@ class TemplateRendererMediaProvider {
});
return null;
}
+
+ _getTextFurigana(media, text, namedArgs) {
+ const {readingMode=null} = namedArgs;
+ const {textFurigana} = media;
+ if (Array.isArray(textFurigana)) {
+ for (const entry of textFurigana) {
+ if (entry.text !== text || entry.readingMode !== readingMode) { continue; }
+ return entry.details;
+ }
+ }
+ this._addRequirement({
+ type: 'textFurigana',
+ text,
+ readingMode
+ });
+ return null;
+ }
}
diff --git a/ext/settings.html b/ext/settings.html
index a8c8149b..0144ddd3 100644
--- a/ext/settings.html
+++ b/ext/settings.html
@@ -2868,6 +2868,10 @@
<td>Sentence, quote, or phrase that the term or kanji appears in from the source content.</td>
</tr>
<tr>
+ <td><code class="anki-field-marker">{sentence-furigana}</code></td>
+ <td>Sentence, quote, or phrase that the term or kanji appears in from the source content, with furigana added.</td>
+ </tr>
+ <tr>
<td><code class="anki-field-marker">{url}</code></td>
<td>Address of the web page in which the term or kanji appeared in.</td>
</tr>
diff --git a/test/data/anki-note-builder-test-results.json b/test/data/anki-note-builder-test-results.json
index a8a7b08a..c10e28a8 100644
--- a/test/data/anki-note-builder-test-results.json
+++ b/test/data/anki-note-builder-test-results.json
@@ -18,6 +18,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"stroke-count": "Stroke count: Unknown",
"tags": "",
"url": "<a href=\"url:\">url:</a>"
@@ -43,6 +44,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix込cloze-suffix",
+ "sentence-furigana": "cloze-prefix込cloze-suffix",
"stroke-count": "Stroke count: Unknown",
"tags": "",
"url": "<a href=\"url:\">url:</a>"
@@ -82,6 +84,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
},
@@ -111,6 +114,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "abbr, n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -145,6 +149,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打つcloze-suffix",
+ "sentence-furigana": "cloze-prefix打つcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -174,6 +179,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打つcloze-suffix",
+ "sentence-furigana": "cloze-prefix打つcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -203,6 +209,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打つcloze-suffix",
+ "sentence-furigana": "cloze-prefix打つcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -232,6 +239,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打つcloze-suffix",
+ "sentence-furigana": "cloze-prefix打つcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -261,6 +269,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
},
@@ -290,6 +299,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "abbr, n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -324,6 +334,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -353,6 +364,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -382,6 +394,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -411,6 +424,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -440,6 +454,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -469,6 +484,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -498,6 +514,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -527,6 +544,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -556,6 +574,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
},
@@ -585,6 +604,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "abbr, n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -619,6 +639,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix画像cloze-suffix",
+ "sentence-furigana": "cloze-prefix画像cloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -653,6 +674,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixだcloze-suffix",
+ "sentence-furigana": "cloze-prefixだcloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -687,6 +709,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixダースcloze-suffix",
+ "sentence-furigana": "cloze-prefixダースcloze-suffix",
"tags": "abbr, n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -721,6 +744,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixうつcloze-suffix",
+ "sentence-furigana": "cloze-prefixうつcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -750,6 +774,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixうつcloze-suffix",
+ "sentence-furigana": "cloze-prefixうつcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
}
@@ -784,6 +809,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixぶつcloze-suffix",
+ "sentence-furigana": "cloze-prefixぶつcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -813,6 +839,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixぶつcloze-suffix",
+ "sentence-furigana": "cloze-prefixぶつcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
}
@@ -847,6 +874,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixうちこむcloze-suffix",
+ "sentence-furigana": "cloze-prefixうちこむcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -876,6 +904,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixうちこむcloze-suffix",
+ "sentence-furigana": "cloze-prefixうちこむcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -905,6 +934,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixうちcloze-suffix",
+ "sentence-furigana": "cloze-prefixうちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -934,6 +964,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixうちcloze-suffix",
+ "sentence-furigana": "cloze-prefixうちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
}
@@ -968,6 +999,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixぶちこむcloze-suffix",
+ "sentence-furigana": "cloze-prefixぶちこむcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -997,6 +1029,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixぶちこむcloze-suffix",
+ "sentence-furigana": "cloze-prefixぶちこむcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1026,6 +1059,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixぶちcloze-suffix",
+ "sentence-furigana": "cloze-prefixぶちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1055,6 +1089,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixぶちcloze-suffix",
+ "sentence-furigana": "cloze-prefixぶちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
}
@@ -1089,6 +1124,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixがぞうcloze-suffix",
+ "sentence-furigana": "cloze-prefixがぞうcloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -1135,6 +1171,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1164,6 +1201,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1193,6 +1231,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1222,6 +1261,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1251,6 +1291,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1280,6 +1321,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "abbr, n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -1314,6 +1356,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1343,6 +1386,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1372,6 +1416,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1401,6 +1446,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "abbr, n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -1435,6 +1481,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込んでいませんでしたcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込んでいませんでしたcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1464,6 +1511,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込んでいませんでしたcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込んでいませんでしたcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1493,6 +1541,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込んでいませんでしたcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込んでいませんでしたcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1522,6 +1571,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ち込んでいませんでしたcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ち込んでいませんでしたcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1551,6 +1601,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1580,6 +1631,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1609,6 +1661,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1638,6 +1691,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1667,6 +1721,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1696,6 +1751,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "abbr, n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -1730,6 +1786,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打(う)ち込(こ)むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打(う)ち込(こ)むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1759,6 +1816,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打(う)ち込(こ)むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打(う)ち込(こ)むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1788,6 +1846,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打(う)ち込(こ)むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打(う)ち込(こ)むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1817,6 +1876,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打(う)ち込(こ)むcloze-suffix",
+ "sentence-furigana": "cloze-prefix打(う)ち込(こ)むcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1846,6 +1906,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打(う)ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打(う)ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1875,6 +1936,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打(う)ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打(う)ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1904,6 +1966,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打(う)ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打(う)ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1933,6 +1996,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打(う)ちcloze-suffix",
+ "sentence-furigana": "cloze-prefix打(う)ちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1962,6 +2026,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
},
@@ -1991,6 +2056,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix打cloze-suffix",
+ "sentence-furigana": "cloze-prefix打cloze-suffix",
"tags": "abbr, n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -2025,6 +2091,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix(打)(ち)(込)(む)cloze-suffix",
+ "sentence-furigana": "cloze-prefix(打)(ち)(込)(む)cloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -2054,6 +2121,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix(打)(ち)(込)(む)cloze-suffix",
+ "sentence-furigana": "cloze-prefix(打)(ち)(込)(む)cloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -2083,6 +2151,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix(打)(ち)(込)(む)cloze-suffix",
+ "sentence-furigana": "cloze-prefix(打)(ち)(込)(む)cloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -2112,6 +2181,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix(打)(ち)(込)(む)cloze-suffix",
+ "sentence-furigana": "cloze-prefix(打)(ち)(込)(む)cloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -2141,6 +2211,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix(打)(ち)cloze-suffix",
+ "sentence-furigana": "cloze-prefix(打)(ち)cloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -2170,6 +2241,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix(打)(ち)cloze-suffix",
+ "sentence-furigana": "cloze-prefix(打)(ち)cloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -2199,6 +2271,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix(打)(ち)cloze-suffix",
+ "sentence-furigana": "cloze-prefix(打)(ち)cloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -2228,6 +2301,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix(打)(ち)cloze-suffix",
+ "sentence-furigana": "cloze-prefix(打)(ち)cloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -2257,6 +2331,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix(打)cloze-suffix",
+ "sentence-furigana": "cloze-prefix(打)cloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
},
@@ -2286,6 +2361,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefix(打)cloze-suffix",
+ "sentence-furigana": "cloze-prefix(打)cloze-suffix",
"tags": "abbr, n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -2320,6 +2396,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixtestcloze-suffix",
+ "sentence-furigana": "cloze-prefixtestcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
}
@@ -2354,6 +2431,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixつtestcloze-suffix",
+ "sentence-furigana": "cloze-prefixつtestcloze-suffix",
"tags": "n",
"url": "<a href=\"url:\">url:</a>"
}
@@ -2388,6 +2466,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixtestましたcloze-suffix",
+ "sentence-furigana": "cloze-prefixtestましたcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
}
@@ -2422,6 +2501,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixうちこむcloze-suffix",
+ "sentence-furigana": "cloze-prefixうちこむcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
},
@@ -2451,6 +2531,7 @@
"search-query": "fullQuery",
"selection-text": "",
"sentence": "cloze-prefixうちcloze-suffix",
+ "sentence-furigana": "cloze-prefixうちcloze-suffix",
"tags": "vt",
"url": "<a href=\"url:\">url:</a>"
}
diff --git a/test/test-anki-note-builder.js b/test/test-anki-note-builder.js
index af9cd061..c7d91325 100644
--- a/test/test-anki-note-builder.js
+++ b/test/test-anki-note-builder.js
@@ -128,7 +128,7 @@ async function createVM() {
}
vm.set({TemplateRendererProxy});
- return {vm, AnkiNoteBuilder};
+ return {vm, AnkiNoteBuilder, JapaneseUtil};
}
function getFieldMarkers(type) {
@@ -160,6 +160,7 @@ function getFieldMarkers(type) {
'search-query',
'selection-text',
'sentence',
+ 'sentence-furigana',
'tags',
'url'
];
@@ -180,6 +181,7 @@ function getFieldMarkers(type) {
'search-query',
'selection-text',
'sentence',
+ 'sentence-furigana',
'stroke-count',
'tags',
'url'
@@ -189,13 +191,14 @@ function getFieldMarkers(type) {
}
}
-async function getRenderResults(dictionaryEntries, type, mode, template, AnkiNoteBuilder, write) {
+async function getRenderResults(dictionaryEntries, type, mode, template, AnkiNoteBuilder, JapaneseUtil, write) {
const markers = getFieldMarkers(type);
const fields = [];
for (const marker of markers) {
fields.push([marker, `{${marker}}`]);
}
+ const japaneseUtil = new JapaneseUtil(null);
const clozePrefix = 'cloze-prefix';
const clozeSuffix = 'cloze-suffix';
const results = [];
@@ -211,7 +214,7 @@ async function getRenderResults(dictionaryEntries, type, mode, template, AnkiNot
}
break;
}
- const ankiNoteBuilder = new AnkiNoteBuilder();
+ const ankiNoteBuilder = new AnkiNoteBuilder({japaneseUtil});
const context = {
url: 'url:',
sentence: {
@@ -250,7 +253,7 @@ async function getRenderResults(dictionaryEntries, type, mode, template, AnkiNot
async function main() {
const write = (process.argv[2] === '--write');
- const {vm, AnkiNoteBuilder} = await createVM();
+ const {vm, AnkiNoteBuilder, JapaneseUtil} = await createVM();
const testInputsFilePath = path.join(__dirname, 'data', 'translator-test-inputs.json');
const {optionsPresets, tests} = JSON.parse(fs.readFileSync(testInputsFilePath, {encoding: 'utf8'}));
@@ -270,7 +273,7 @@ async function main() {
const {name, mode, text} = test;
const options = vm.buildOptions(optionsPresets, test.options);
const {dictionaryEntries} = clone(await vm.translator.findTerms(mode, text, options));
- const results = mode !== 'simple' ? clone(await getRenderResults(dictionaryEntries, 'terms', mode, template, AnkiNoteBuilder, write)) : null;
+ const results = mode !== 'simple' ? clone(await getRenderResults(dictionaryEntries, 'terms', mode, template, AnkiNoteBuilder, JapaneseUtil, write)) : null;
actualResults1.push({name, results});
if (!write) {
assert.deepStrictEqual(results, expected1.results);
@@ -282,7 +285,7 @@ async function main() {
const {name, text} = test;
const options = vm.buildOptions(optionsPresets, test.options);
const dictionaryEntries = clone(await vm.translator.findKanji(text, options));
- const results = clone(await getRenderResults(dictionaryEntries, 'kanji', null, template, AnkiNoteBuilder, write));
+ const results = clone(await getRenderResults(dictionaryEntries, 'kanji', null, template, AnkiNoteBuilder, JapaneseUtil, write));
actualResults1.push({name, results});
if (!write) {
assert.deepStrictEqual(results, expected1.results);