aboutsummaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/css/settings.css7
-rw-r--r--ext/data/templates/anki-field-templates-upgrade-v21.handlebars161
-rw-r--r--ext/data/templates/default-anki-field-templates.handlebars54
-rw-r--r--ext/js/background/backend.js20
-rw-r--r--ext/js/data/options-util.js35
-rw-r--r--ext/js/pages/welcome-main.js7
-rw-r--r--ext/js/templates/sandbox/anki-template-renderer.js54
-rw-r--r--ext/welcome.html27
8 files changed, 284 insertions, 81 deletions
diff --git a/ext/css/settings.css b/ext/css/settings.css
index eaebc3af..a2618d88 100644
--- a/ext/css/settings.css
+++ b/ext/css/settings.css
@@ -2167,6 +2167,13 @@ button.hotkey-list-item-enabled-button[data-scope-count='0'] {
display: none;
}
+.warn-custom-templates-notification {
+ border: 1px solid var(--danger-color);
+}
+:root:not([data-warn-custom-templates=true]) .warn-custom-templates-notification {
+ display: none;
+}
+
.test-anki-note-viewer-container {
margin-top: 0.85em;
display: flex;
diff --git a/ext/data/templates/anki-field-templates-upgrade-v21.handlebars b/ext/data/templates/anki-field-templates-upgrade-v21.handlebars
new file mode 100644
index 00000000..33c4dc6c
--- /dev/null
+++ b/ext/data/templates/anki-field-templates-upgrade-v21.handlebars
@@ -0,0 +1,161 @@
+{{<<<<<<<}}
+{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}
+{{=======}}
+{{formatGlossary ../dictionary .}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#furigana}}{{{.}}}{{/furigana~}}
+{{=======}}
+{{~furigana .~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{#furigana}}{{{definition}}}{{/furigana}}
+{{=======}}
+{{furigana definition}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#furigana expression reading~}}{{~/furigana~}}
+{{=======}}
+{{~furigana expression reading~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#furigana expression reading}}{{/furigana~}}
+{{=======}}
+{{~furigana expression reading~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#furiganaPlain}}{{{.}}}{{/furiganaPlain~}}
+{{=======}}
+{{~furiganaPlain .~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{#furiganaPlain}}{{{definition}}}{{/furiganaPlain}}
+{{=======}}
+{{furiganaPlain definition}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#furiganaPlain expression reading~}}{{~/furiganaPlain~}}
+{{=======}}
+{{~furiganaPlain expression reading~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#furiganaPlain expression reading}}{{/furiganaPlain~}}
+{{=======}}
+{{~furiganaPlain expression reading~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{#getMedia "audio"}}{{/getMedia}}
+{{=======}}
+{{getMedia "audio"}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{#getMedia "screenshot"}}{{/getMedia}}
+{{=======}}
+{{getMedia "screenshot"}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{#getMedia "clipboardImage"}}{{/getMedia}}
+{{=======}}
+{{getMedia "clipboardImage"}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{#getMedia "clipboardText"}}{{/getMedia}}
+{{=======}}
+{{getMedia "clipboardText"}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{#getMedia "selectionText"}}{{/getMedia}}
+{{=======}}
+{{getMedia "selectionText"}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{#getMedia "textFurigana" definition.cloze.sentence escape=false}}{{/getMedia}}
+{{=======}}
+{{getMedia "textFurigana" definition.cloze.sentence escape=false}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}{{~/pronunciation~}}
+{{=======}}
+{{~pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#set "any" false}}{{/set~}}
+{{=======}}
+{{~set "any" false~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#set "any" true}}{{/set~}}
+{{=======}}
+{{~set "any" true~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#set "previousDictionary" dictionary~}}{{~/set~}}
+{{=======}}
+{{~set "previousDictionary" dictionary~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}}
+{{=======}}
+{{~set "exclusive" (spread exclusiveExpressions exclusiveReadings)~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#set "separator" ""~}}{{/set~}}
+{{=======}}
+{{~set "separator" ""~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#get "separator"}}{{/get~}}
+{{=======}}
+{{~get "separator"~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#set "found" false}}{{/set~}}
+{{=======}}
+{{~set "found" false~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#set "found" true}}{{/set~}}
+{{=======}}
+{{~set "found" true~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#set "first" true}}{{/set~}}
+{{=======}}
+{{~set "first" true~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#set "first" false~}}{{~/set~}}
+{{=======}}
+{{~set "first" false~}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{~#set (concat "used_" .) true~}}{{~/set~}}
+{{=======}}
+{{~set (concat "used_" .) true~}}
+{{>>>>>>>}}
diff --git a/ext/data/templates/default-anki-field-templates.handlebars b/ext/data/templates/default-anki-field-templates.handlebars
index 31d5d13f..d94f6d70 100644
--- a/ext/data/templates/default-anki-field-templates.handlebars
+++ b/ext/data/templates/default-anki-field-templates.handlebars
@@ -1,19 +1,19 @@
{{#*inline "glossary-single"}}
{{~#unless brief~}}
{{~#scope~}}
- {{~#set "any" false}}{{/set~}}
+ {{~set "any" false~}}
{{~#each definitionTags~}}
{{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{name}}
- {{~#set "any" true}}{{/set~}}
+ {{~set "any" true~}}
{{~/if~}}
{{~/each~}}
{{~#unless noDictionaryTag~}}
{{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
{{~#if (get "any")}}, {{else}}<i>({{/if~}}
{{dictionary}}
- {{~#set "any" true}}{{/set~}}
+ {{~set "any" true~}}
{{~/if~}}
{{~/unless~}}
{{~#if (get "any")}})</i> {{/if~}}
@@ -21,18 +21,18 @@
{{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
{{~/unless~}}
{{~#if (op "<=" glossary.length 1)~}}
- {{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{/each}}
+ {{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}
{{~else if @root.compactGlossaries~}}
- {{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{#unless @last}} | {{/unless}}{{/each}}
+ {{#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each}}
{{~else~}}
- <ul>{{#each glossary}}<li>{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}</li>{{/each}}</ul>
+ <ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul>
{{~/if~}}
- {{~#set "previousDictionary" dictionary~}}{{~/set~}}
+ {{~set "previousDictionary" dictionary~}}
{{/inline}}
{{#*inline "audio"}}
{{~#if (hasMedia "audio")~}}
- [sound:{{#getMedia "audio"}}{{/getMedia}}]
+ [sound:{{getMedia "audio"}}]
{{~/if~}}
{{/inline}}
@@ -78,22 +78,22 @@
{{#*inline "furigana"}}
{{~#if merge~}}
{{~#each definition.expressions~}}
- <span class="expression-{{termFrequency}}">{{~#furigana}}{{{.}}}{{/furigana~}}</span>
+ <span class="expression-{{termFrequency}}">{{~furigana .~}}</span>
{{~#unless @last}}、{{/unless~}}
{{~/each~}}
{{~else~}}
- {{#furigana}}{{{definition}}}{{/furigana}}
+ {{furigana definition}}
{{~/if~}}
{{/inline}}
{{#*inline "furigana-plain"}}
{{~#if merge~}}
{{~#each definition.expressions~}}
- <span class="expression-{{termFrequency}}">{{~#furiganaPlain}}{{{.}}}{{/furiganaPlain~}}</span>
+ <span class="expression-{{termFrequency}}">{{~furiganaPlain .~}}</span>
{{~#unless @last}}、{{/unless~}}
{{~/each~}}
{{~else~}}
- {{#furiganaPlain}}{{{definition}}}{{/furiganaPlain}}
+ {{furiganaPlain definition}}
{{~/if~}}
{{/inline}}
@@ -174,7 +174,7 @@
{{#*inline "screenshot"}}
{{~#if (hasMedia "screenshot")~}}
- <img src="{{#getMedia "screenshot"}}{{/getMedia}}" />
+ <img src="{{getMedia "screenshot"}}" />
{{~/if~}}
{{/inline}}
@@ -184,16 +184,16 @@
{{! Pitch Accents }}
{{#*inline "pitch-accent-item"}}
- {{~#pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}{{~/pronunciation~}}
+ {{~pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
{{/inline}}
{{#*inline "pitch-accent-item-disambiguation"}}
{{~#scope~}}
- {{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}}
+ {{~set "exclusive" (spread exclusiveExpressions exclusiveReadings)~}}
{{~#if (op ">" (property (get "exclusive") "length") 0)~}}
- {{~#set "separator" ""~}}{{/set~}}
+ {{~set "separator" ""~}}
<em>({{#each (get "exclusive")~}}
- {{~#get "separator"}}{{/get~}}{{{.}}}
+ {{~get "separator"~}}{{{.}}}
{{~/each}} only) </em>
{{~/if~}}
{{~/scope~}}
@@ -231,12 +231,12 @@
{{#*inline "clipboard-image"}}
{{~#if (hasMedia "clipboardImage")~}}
- <img src="{{#getMedia "clipboardImage"}}{{/getMedia}}" />
+ <img src="{{getMedia "clipboardImage"}}" />
{{~/if~}}
{{/inline}}
{{#*inline "clipboard-text"}}
- {{~#if (hasMedia "clipboardText")}}{{#getMedia "clipboardText"}}{{/getMedia}}{{/if~}}
+ {{~#if (hasMedia "clipboardText")}}{{getMedia "clipboardText"}}{{/if~}}
{{/inline}}
{{#*inline "conjugation"}}
@@ -255,7 +255,7 @@
<li>
{{~#if (op "!==" ../definition.type "kanji")~}}
{{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
- {{~#furigana expression reading~}}{{~/furigana~}}
+ {{~furigana expression reading~}}
) {{/if~}}
{{~/if~}}
{{~dictionary}}: {{frequency~}}
@@ -267,10 +267,10 @@
{{#*inline "stroke-count"}}
{{~#scope~}}
- {{~#set "found" false}}{{/set~}}
+ {{~set "found" false~}}
{{~#each definition.stats.misc~}}
{{~#if (op "===" name "strokes")~}}
- {{~#set "found" true}}{{/set~}}
+ {{~set "found" true~}}
Stroke count: {{value}}
{{~/if~}}
{{~/each~}}
@@ -295,14 +295,14 @@
{{#*inline "part-of-speech"}}
{{~#scope~}}
{{~#if (op "!==" definition.type "kanji")~}}
- {{~#set "first" true}}{{/set~}}
+ {{~set "first" true~}}
{{~#each definition.expressions~}}
{{~#each wordClasses~}}
{{~#unless (get (concat "used_" .))~}}
{{~> part-of-speech-pretty . ~}}
{{~#unless (get "first")}}, {{/unless~}}
- {{~#set (concat "used_" .) true~}}{{~/set~}}
- {{~#set "first" false~}}{{~/set~}}
+ {{~set (concat "used_" .) true~}}
+ {{~set "first" false~}}
{{~/unless~}}
{{~/each~}}
{{~/each~}}
@@ -316,13 +316,13 @@
{{/inline}}
{{#*inline "selection-text"}}
- {{~#if (hasMedia "selectionText")}}{{#getMedia "selectionText"}}{{/getMedia}}{{/if~}}
+ {{~#if (hasMedia "selectionText")}}{{getMedia "selectionText"}}{{/if~}}
{{/inline}}
{{#*inline "sentence-furigana"}}
{{~#if definition.cloze~}}
{{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}}
- {{#getMedia "textFurigana" definition.cloze.sentence escape=false}}{{/getMedia}}
+ {{getMedia "textFurigana" definition.cloze.sentence escape=false}}
{{~else~}}
{{definition.cloze.sentence}}
{{~/if~}}
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js
index 308ae4d5..8e8e6945 100644
--- a/ext/js/background/backend.js
+++ b/ext/js/background/backend.js
@@ -2127,20 +2127,12 @@ class Backend {
}
async _openWelcomeGuidePageOnce() {
- if (isObject(chrome.storage) && isObject(chrome.storage.session)) {
- // Chrome
- chrome.storage.session.get(['openedWelcomePage']).then((result) => {
- if (!result.openedWelcomePage) {
- this._openWelcomeGuidePage();
- chrome.storage.session.set({'openedWelcomePage': true});
- }
- });
- } else {
- // Firefox (storage.session is not supported yet)
- // NOTE: This means that the welcome page will repeatedly open in Firefox
- // until they support storage.session.
- this._openWelcomeGuidePage();
- }
+ chrome.storage.session.get(['openedWelcomePage']).then((result) => {
+ if (!result.openedWelcomePage) {
+ this._openWelcomeGuidePage();
+ chrome.storage.session.set({'openedWelcomePage': true});
+ }
+ });
}
async _openWelcomeGuidePage() {
diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js
index 2674701f..1f2ffb05 100644
--- a/ext/js/data/options-util.js
+++ b/ext/js/data/options-util.js
@@ -470,7 +470,8 @@ class OptionsUtil {
{async: false, update: this._updateVersion17.bind(this)},
{async: false, update: this._updateVersion18.bind(this)},
{async: false, update: this._updateVersion19.bind(this)},
- {async: false, update: this._updateVersion20.bind(this)}
+ {async: false, update: this._updateVersion20.bind(this)},
+ {async: true, update: this._updateVersion21.bind(this)}
];
if (typeof targetVersion === 'number' && targetVersion < result.length) {
result.splice(targetVersion);
@@ -997,4 +998,36 @@ class OptionsUtil {
}
return options;
}
+
+ async _updateVersion21(options) {
+ await this._applyAnkiFieldTemplatesPatch(options, '/data/templates/anki-field-templates-upgrade-v21.handlebars');
+
+ let customTemplates = false;
+ for (const {options: profileOptions} of options.profiles) {
+ if (profileOptions.anki.fieldTemplates !== null) {
+ customTemplates = true;
+ }
+ }
+
+ if (customTemplates && isObject(chrome.storage)) {
+ chrome.storage.session.set({'needsCustomTemplatesWarning': true});
+ await this._createTab(chrome.runtime.getURL('/welcome.html'));
+ chrome.storage.session.set({'openedWelcomePage': true});
+ }
+
+ return options;
+ }
+
+ _createTab(url) {
+ return new Promise((resolve, reject) => {
+ chrome.tabs.create({url}, (tab) => {
+ const e = chrome.runtime.lastError;
+ if (e) {
+ reject(new Error(e.message));
+ } else {
+ resolve(tab);
+ }
+ });
+ });
+ }
}
diff --git a/ext/js/pages/welcome-main.js b/ext/js/pages/welcome-main.js
index 521ce2c2..8039dae5 100644
--- a/ext/js/pages/welcome-main.js
+++ b/ext/js/pages/welcome-main.js
@@ -58,6 +58,13 @@ async function setupGenericSettingsController(genericSettingController) {
setupEnvironmentInfo();
+ chrome.storage.session.get({'needsCustomTemplatesWarning': false}).then((result) => {
+ if (result.needsCustomTemplatesWarning) {
+ document.documentElement.dataset.warnCustomTemplates = 'true';
+ chrome.storage.session.remove(['needsCustomTemplatesWarning']);
+ }
+ });
+
const preparePromises = [];
const modalController = new ModalController();
diff --git a/ext/js/templates/sandbox/anki-template-renderer.js b/ext/js/templates/sandbox/anki-template-renderer.js
index 789f0942..766c7798 100644
--- a/ext/js/templates/sandbox/anki-template-renderer.js
+++ b/ext/js/templates/sandbox/anki-template-renderer.js
@@ -68,9 +68,7 @@ class AnkiTemplateRenderer {
['dumpObject', this._dumpObject.bind(this)],
['furigana', this._furigana.bind(this)],
['furiganaPlain', this._furiganaPlain.bind(this)],
- ['kanjiLinks', this._kanjiLinks.bind(this)],
['multiLine', this._multiLine.bind(this)],
- ['sanitizeCssClass', this._sanitizeCssClass.bind(this)],
['regexReplace', this._regexReplace.bind(this)],
['regexMatch', this._regexMatch.bind(this)],
['mergeTags', this._mergeTags.bind(this)],
@@ -132,10 +130,14 @@ class AnkiTemplateRenderer {
return Handlebars.Utils.escapeExpression(text);
}
+ _safeString(text) {
+ return new Handlebars.SafeString(text);
+ }
+
// Template helpers
- _dumpObject(context, options) {
- const dump = JSON.stringify(options.fn(context), null, 4);
+ _dumpObject(context, object) {
+ const dump = JSON.stringify(object, null, 4);
return this._escape(dump);
}
@@ -145,14 +147,16 @@ class AnkiTemplateRenderer {
let result = '';
for (const {text, reading: reading2} of segs) {
- if (reading2.length > 0) {
- result += `<ruby>${text}<rt>${reading2}</rt></ruby>`;
+ const safeText = this._escape(text);
+ const safeReading = this._escape(reading2);
+ if (safeReading.length > 0) {
+ result += `<ruby>${safeText}<rt>${safeReading}</rt></ruby>`;
} else {
- result += text;
+ result += safeText;
}
}
- return result;
+ return this._safeString(result);
}
_furiganaPlain(context, ...args) {
@@ -173,29 +177,16 @@ class AnkiTemplateRenderer {
}
_getFuriganaExpressionAndReading(context, ...args) {
- const options = args[args.length - 1];
if (args.length >= 3) {
return {expression: args[0], reading: args[1]};
- } else {
- const {expression, reading} = options.fn(context);
+ } else if (args.length === 2) {
+ const {expression, reading} = args[0];
return {expression, reading};
+ } else {
+ return void 0;
}
}
- _kanjiLinks(context, options) {
- const jp = this._japaneseUtil;
- let result = '';
- for (const c of options.fn(context)) {
- if (jp.isCodePointKanji(c.codePointAt(0))) {
- result += `<a href="#" class="kanji-link">${c}</a>`;
- } else {
- result += c;
- }
- }
-
- return result;
- }
-
_stringToMultiLineHtml(string) {
return string.split('\n').join('<br>');
}
@@ -204,10 +195,6 @@ class AnkiTemplateRenderer {
return this._stringToMultiLineHtml(options.fn(context));
}
- _sanitizeCssClass(context, options) {
- return options.fn(context).replace(/[^_a-z0-9\u00a0-\uffff]/ig, '_');
- }
-
_regexReplace(context, ...args) {
// Usage:
// {{#regexReplace regex string [flags] [content]...}}content{{/regexReplace}}
@@ -219,7 +206,7 @@ class AnkiTemplateRenderer {
const options = args[argCount];
let value = typeof options.fn === 'function' ? options.fn(context) : '';
if (argCount > 3) {
- value = `${args.slice(3).join('')}${value}`;
+ value = `${args.slice(3, -1).join('')}${value}`;
}
if (argCount > 1) {
try {
@@ -243,7 +230,7 @@ class AnkiTemplateRenderer {
const options = args[argCount];
let value = typeof options.fn === 'function' ? options.fn(context) : '';
if (argCount > 2) {
- value = `${args.slice(2).join('')}${value}`;
+ value = `${args.slice(2, -1).join('')}${value}`;
}
if (argCount > 0) {
try {
@@ -490,7 +477,7 @@ class AnkiTemplateRenderer {
this._normalizeHtml(container, styleApplier, datasetKeyIgnorePattern);
const result = container.innerHTML;
container.textContent = '';
- return result;
+ return this._safeString(result);
}
_normalizeHtml(root, styleApplier, datasetKeyIgnorePattern) {
@@ -543,9 +530,8 @@ class AnkiTemplateRenderer {
return instance;
}
- _formatGlossary(context, dictionary, options) {
+ _formatGlossary(context, dictionary, content, options) {
const data = options.data.root;
- const content = options.fn(context);
if (typeof content === 'string') { return this._stringToMultiLineHtml(this._escape(content)); }
if (!(typeof content === 'object' && content !== null)) { return ''; }
switch (content.type) {
diff --git a/ext/welcome.html b/ext/welcome.html
index 14e98367..56167866 100644
--- a/ext/welcome.html
+++ b/ext/welcome.html
@@ -25,6 +25,19 @@
<h1>Welcome to Yomitan!</h1>
+ <!-- Notifications -->
+ <div class="settings-group settings-group-top-margin warn-custom-templates-notification">
+ <div class="settings-item">
+ <div class="settings-item-inner settings-item-inner-wrappable"><div class="settings-item-left"><div class="settings-item-label">
+ <p>
+ There are custom Anki templates in your settings. Note that <a href="https://github.com/themoeway/yomitan#custom-templates" target="_blank" rel="noopener noreferrer">some syntax has changed from previous versions of Yomitan.</a>
+ Please ensure that your custom templates are using the updated syntax.
+ </p>
+ </div></div></div>
+ </div>
+ </div>
+
+ <!-- Content -->
<h2>Here are some basics to get started</h2>
<div class="settings-group">
<div class="settings-item">
@@ -49,10 +62,9 @@
<div class="settings-item">
<div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label">
Yomitan requires one or more dictionaries to be installed in order to look up terms, kanji, and other information.
- Several downloadable dictionaries can be found on the <a href="https://github.com/themoeway/yomitan#dictionaries" target="_blank" rel="noopener noreferrer">Yomitan homepage</a>,
- allowing you to choose the dictionaries most relevant for you.
+ Several downloadable dictionaries can be found on the <a href="https://github.com/themoeway/yomitan#dictionaries" target="_blank" rel="noopener noreferrer">Yomitan homepage</a>.
Dictionaries can be configured using the button below,
- or later from the the <a href="/settings.html" rel="noopener">Settings</a> page.
+ or later from the <a href="/settings.html" rel="noopener">Settings</a> page.
</div></div></div>
<div class="settings-item-children settings-item-children-group">
<div class="settings-item settings-item-button" data-modal-action="show,dictionaries"><div class="settings-item-inner">
@@ -67,12 +79,17 @@
</div>
<div class="settings-item">
<div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label">
- You can also import an exported collection of dictionaries to migrate from a different device or browser from the <a href="/settings.html#!backup">Backup section of the Settings</a> page.
+ You can also import an exported collection of dictionaries from the <a href="/settings.html#!backup">Backup section of the Settings</a> page.
<br><br>
- If you are migrating from Yomichan, you may be particularly interested in migrating your data from Yomichan into Yomitan.
+ If you are migrating from Yomichan, you may be interested in importing your data into Yomitan.
Please follow instructions from <a href="https://github.com/themoeway/yomitan#migrating-from-yomichan" target="_blank" rel="noopener noreferrer">Yomitan's README</a> for that.
+
+ <br><br>
+
+ If you are using or planning to use custom templates for Anki note creation, note that <a href="https://github.com/themoeway/yomitan#custom-templates" target="_blank" rel="noopener noreferrer">some syntax has changed from Yomichan and Yomibaba.</a>
+ Please ensure that your custom templates are using the updated syntax.
</div></div></div>
</div>
<div class="settings-item">