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
This commit is contained in:
toasted-nutbread 2021-07-09 17:48:27 -04:00 committed by GitHub
parent 0d16709547
commit 8c68fa4d94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 217 additions and 27 deletions

View File

@ -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.

View File

@ -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}}
{{=======}}

View File

@ -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") ~}}

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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(); }],

View File

@ -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',

View File

@ -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() {

View File

@ -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;
}
}

View File

@ -2867,6 +2867,10 @@
<td><code class="anki-field-marker">{sentence}</code></td>
<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>

View File

@ -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>"
}

View File

@ -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);