aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/bg/js/dictionary.js81
-rw-r--r--ext/mixed/js/extension.js15
2 files changed, 58 insertions, 38 deletions
diff --git a/ext/bg/js/dictionary.js b/ext/bg/js/dictionary.js
index 191058c1..e786c4e2 100644
--- a/ext/bg/js/dictionary.js
+++ b/ext/bg/js/dictionary.js
@@ -327,45 +327,50 @@ function dictFieldSplit(field) {
}
async function dictFieldFormat(field, definition, mode, options) {
- const markers = [
- 'audio',
- 'character',
- 'cloze-body',
- 'cloze-prefix',
- 'cloze-suffix',
- 'dictionary',
- 'expression',
- 'furigana',
- 'furigana-plain',
- 'glossary',
- 'glossary-brief',
- 'kunyomi',
- 'onyomi',
- 'reading',
- 'screenshot',
- 'sentence',
- 'tags',
- 'url'
- ];
-
- for (const marker of markers) {
- const data = {
- marker,
- definition,
- group: options.general.resultOutputMode === 'group',
- merge: options.general.resultOutputMode === 'merge',
- modeTermKanji: mode === 'term-kanji',
- modeTermKana: mode === 'term-kana',
- modeKanji: mode === 'kanji',
- compactGlossaries: options.general.compactGlossaries
- };
-
- const html = await apiTemplateRender(options.anki.fieldTemplates, data, true);
- field = field.replace(`{${marker}}`, html);
- }
-
- return field;
+ const data = {
+ marker: null,
+ definition,
+ group: options.general.resultOutputMode === 'group',
+ merge: options.general.resultOutputMode === 'merge',
+ modeTermKanji: mode === 'term-kanji',
+ modeTermKana: mode === 'term-kana',
+ modeKanji: mode === 'kanji',
+ compactGlossaries: options.general.compactGlossaries
+ };
+ const markers = dictFieldFormat.markers;
+ const pattern = /\{([\w\-]+)\}/g;
+ return await stringReplaceAsync(field, pattern, async (g0, marker) => {
+ if (!markers.has(marker)) {
+ return g0;
+ }
+ data.marker = marker;
+ try {
+ return await apiTemplateRender(options.anki.fieldTemplates, data, true);
+ } catch (e) {
+ return `{${marker}-render-error}`;
+ }
+ });
}
+dictFieldFormat.markers = new Set([
+ 'audio',
+ 'character',
+ 'cloze-body',
+ 'cloze-prefix',
+ 'cloze-suffix',
+ 'dictionary',
+ 'expression',
+ 'furigana',
+ 'furigana-plain',
+ 'glossary',
+ 'glossary-brief',
+ 'kunyomi',
+ 'onyomi',
+ 'reading',
+ 'screenshot',
+ 'sentence',
+ 'tags',
+ 'url'
+]);
async function dictNoteFormat(definition, mode, options) {
const note = {fields: {}, tags: options.anki.tags};
diff --git a/ext/mixed/js/extension.js b/ext/mixed/js/extension.js
index 54862e19..12ed9c1f 100644
--- a/ext/mixed/js/extension.js
+++ b/ext/mixed/js/extension.js
@@ -133,3 +133,18 @@ function promiseTimeout(delay, resolveValue) {
return promise;
}
+
+function stringReplaceAsync(str, regex, replacer) {
+ let match;
+ let index = 0;
+ const parts = [];
+ while ((match = regex.exec(str)) !== null) {
+ parts.push(str.substring(index, match.index), replacer(...match, match.index, str));
+ index = regex.lastIndex;
+ }
+ if (parts.length === 0) {
+ return Promise.resolve(str);
+ }
+ parts.push(str.substring(index));
+ return Promise.all(parts).then(v => v.join(''));
+}