aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--docs/templates.md18
-rw-r--r--ext/bg/data/anki-field-templates-upgrade-v6.handlebars17
-rw-r--r--ext/bg/data/default-anki-field-templates.handlebars17
-rw-r--r--ext/bg/js/anki-note-builder.js10
-rw-r--r--ext/bg/js/settings/anki-controller.js1
-rw-r--r--ext/bg/js/template-renderer.js31
-rw-r--r--ext/mixed/js/japanese.js10
-rw-r--r--test/test-japanese.js19
9 files changed, 108 insertions, 17 deletions
diff --git a/README.md b/README.md
index fd8e23a3..d487ad07 100644
--- a/README.md
+++ b/README.md
@@ -163,6 +163,7 @@ Flashcard fields can be configured with the following steps:
`{dictionary}` | Name of the dictionary from which the card is being created (unavailable in *grouped* mode).
`{document-title}` | Title of the web page that the term appeared in.
`{expression}` | Term expressed as kanji (will be displayed in kana if kanji is not available).
+ `{frequencies}` | Frequency information for the term.
`{furigana}` | Term expressed as kanji with furigana displayed above it (e.g. <ruby>日本語<rt>にほんご</rt></ruby>).
`{furigana-plain}` | Term expressed as kanji with furigana displayed next to it in brackets (e.g. 日本語[にほんご]).
`{glossary}` | List of definitions for the term (output format depends on whether running in *grouped* mode).
@@ -188,6 +189,7 @@ Flashcard fields can be configured with the following steps:
`{cloze-suffix}` | Fragment of the containing `{sentence}` starting at the end of `{cloze-body}` until the end of `{sentence}`.
`{dictionary}` | Name of the dictionary from which the card is being created.
`{document-title}` | Title of the web page that the kanji appeared in.
+ `{frequencies}` | Frequency information for the kanji.
`{glossary}` | List of definitions for the kanji.
`{kunyomi}` | Kunyomi (Japanese reading) for the kanji expressed as katakana.
`{onyomi}` | Onyomi (Chinese reading) for the kanji expressed as hiragana.
diff --git a/docs/templates.md b/docs/templates.md
index 1c9081d2..7425bc4a 100644
--- a/docs/templates.md
+++ b/docs/templates.md
@@ -44,21 +44,27 @@ This function can be helpful for debugging values when creating templates.
### `furigana`
-Converts a definition to its furigana representation.
+Converts a definition or expression/reading pair to its furigana representation.
<details>
<summary>Syntax:</summary>
- <code>{{#furigana}}<i>&lt;definition&gt;</i>{{/furigana}}</code>
+ <code>{{#furigana}}<i>&lt;definition&gt;</i>{{/furigana}}</code><br>
+ <code>{{#furigana <i>expression</i> <i>reading</i>}}{{/furigana}}</code><br>
* _`definition`_ <br>
The definition to convert.
+ * _`expression`_ <br>
+ The expression to convert.
+ * _`reading`_ <br>
+ The reading to convert.
</details>
<details>
<summary>Example:</summary>
```handlebars
{{#furigana}}{{.}}{{/furigana}}
+ {{#furigana "読む" "よむ"}}{{/furigana}}
```
Output:
@@ -73,21 +79,27 @@ Converts a definition to its furigana representation.
### `furiganaPlain`
-Converts a definition to its simplified furigana representation.
+Converts a definition or expression/reading pair to its simplified furigana representation.
<details>
<summary>Syntax:</summary>
<code>{{#furiganaPlain}}<i>&lt;definition&gt;</i>{{/furigana}}</code>
+ <code>{{#furiganaPlain <i>expression</i> <i>reading</i>}}{{/furiganaPlain}}</code><br>
* _`definition`_ <br>
The definition to convert.
+ * _`expression`_ <br>
+ The expression to convert.
+ * _`reading`_ <br>
+ The reading to convert.
</details>
<details>
<summary>Example:</summary>
```handlebars
{{~#furiganaPlain~}}{{.}}{{~/furiganaPlain~}}
+ {{#furiganaPlain "読む" "よむ"}}{{/furiganaPlain}}
```
Output:
diff --git a/ext/bg/data/anki-field-templates-upgrade-v6.handlebars b/ext/bg/data/anki-field-templates-upgrade-v6.handlebars
index 33a2f949..809423ce 100644
--- a/ext/bg/data/anki-field-templates-upgrade-v6.handlebars
+++ b/ext/bg/data/anki-field-templates-upgrade-v6.handlebars
@@ -6,3 +6,20 @@
{{~/each~}}
{{~/if~}}
{{/inline}}
+
+{{#*inline "frequencies"}}
+ {{~#if (op ">" definition.frequencies.length 0)~}}
+ <ul style="text-align: left;">
+ {{~#each definition.frequencies~}}
+ <li>
+ {{~#if (op "!==" ../definition.type "kanji")~}}
+ {{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
+ {{~#furigana expression reading~}}{{~/furigana~}}
+ ) {{/if~}}
+ {{~/if~}}
+ {{~dictionary}}: {{frequency~}}
+ </li>
+ {{~/each~}}
+ </ul>
+ {{~/if~}}
+{{/inline}}
diff --git a/ext/bg/data/default-anki-field-templates.handlebars b/ext/bg/data/default-anki-field-templates.handlebars
index 0b0e9ca6..1024e2e6 100644
--- a/ext/bg/data/default-anki-field-templates.handlebars
+++ b/ext/bg/data/default-anki-field-templates.handlebars
@@ -306,4 +306,21 @@
{{~/if~}}
{{/inline}}
+{{#*inline "frequencies"}}
+ {{~#if (op ">" definition.frequencies.length 0)~}}
+ <ul style="text-align: left;">
+ {{~#each definition.frequencies~}}
+ <li>
+ {{~#if (op "!==" ../definition.type "kanji")~}}
+ {{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
+ {{~#furigana expression reading~}}{{~/furigana~}}
+ ) {{/if~}}
+ {{~/if~}}
+ {{~dictionary}}: {{frequency~}}
+ </li>
+ {{~/each~}}
+ </ul>
+ {{~/if~}}
+{{/inline}}
+
{{~> (lookup . "marker") ~}}
diff --git a/ext/bg/js/anki-note-builder.js b/ext/bg/js/anki-note-builder.js
index 33cd3a0b..b6114e4b 100644
--- a/ext/bg/js/anki-note-builder.js
+++ b/ext/bg/js/anki-note-builder.js
@@ -108,9 +108,19 @@ class AnkiNoteBuilder {
_createNoteData(definition, mode, context, resultOutputMode, glossaryLayoutMode, compactTags) {
const pitches = DictionaryDataUtil.getPitchAccentInfos(definition);
const pitchCount = pitches.reduce((i, v) => i + v.pitches.length, 0);
+ const uniqueExpressions = new Set();
+ const uniqueReadings = new Set();
+ if (definition.type !== 'kanji') {
+ for (const {expression, reading} of definition.expressions) {
+ uniqueExpressions.add(expression);
+ uniqueReadings.add(reading);
+ }
+ }
return {
marker: null,
definition,
+ uniqueExpressions: [...uniqueExpressions],
+ uniqueReadings: [...uniqueReadings],
pitches,
pitchCount,
group: resultOutputMode === 'group',
diff --git a/ext/bg/js/settings/anki-controller.js b/ext/bg/js/settings/anki-controller.js
index d9b1591e..957f86d9 100644
--- a/ext/bg/js/settings/anki-controller.js
+++ b/ext/bg/js/settings/anki-controller.js
@@ -83,6 +83,7 @@ class AnkiController {
'dictionary',
'document-title',
'expression',
+ 'frequencies',
'furigana',
'furigana-plain',
'glossary',
diff --git a/ext/bg/js/template-renderer.js b/ext/bg/js/template-renderer.js
index 5dd33814..c1995acd 100644
--- a/ext/bg/js/template-renderer.js
+++ b/ext/bg/js/template-renderer.js
@@ -117,13 +117,13 @@ class TemplateRenderer {
return this._escape(dump);
}
- _furigana(context, options) {
- const definition = options.fn(context);
- const segs = jp.distributeFurigana(definition.expression, definition.reading);
+ _furigana(context, ...args) {
+ const {expression, reading} = this._getFuriganaExpressionAndReading(context, ...args);
+ const segs = jp.distributeFurigana(expression, reading);
let result = '';
for (const seg of segs) {
- if (seg.furigana) {
+ if (seg.furigana.length > 0) {
result += `<ruby>${seg.text}<rt>${seg.furigana}</rt></ruby>`;
} else {
result += seg.text;
@@ -133,20 +133,31 @@ class TemplateRenderer {
return result;
}
- _furiganaPlain(context, options) {
- const definition = options.fn(context);
- const segs = jp.distributeFurigana(definition.expression, definition.reading);
+ _furiganaPlain(context, ...args) {
+ const {expression, reading} = this._getFuriganaExpressionAndReading(context, ...args);
+ const segs = jp.distributeFurigana(expression, reading);
let result = '';
for (const seg of segs) {
- if (seg.furigana) {
- result += ` ${seg.text}[${seg.furigana}]`;
+ if (seg.furigana.length > 0) {
+ if (result.length > 0) { result += ' '; }
+ result += `${seg.text}[${seg.furigana}]`;
} else {
result += seg.text;
}
}
- return result.trimLeft();
+ return result;
+ }
+
+ _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);
+ return {expression, reading};
+ }
}
_kanjiLinks(context, options) {
diff --git a/ext/mixed/js/japanese.js b/ext/mixed/js/japanese.js
index ee0ac777..2177ceee 100644
--- a/ext/mixed/js/japanese.js
+++ b/ext/mixed/js/japanese.js
@@ -411,9 +411,9 @@ const jp = (() => {
// Furigana distribution
distributeFurigana(expression, reading) {
- const fallback = [{furigana: reading, text: expression}];
- if (!reading) {
- return fallback;
+ if (!reading || reading === expression) {
+ // Same
+ return [{furigana: '', text: expression}];
}
let isAmbiguous = false;
@@ -471,7 +471,9 @@ const jp = (() => {
if (segments && !isAmbiguous) {
return segments;
}
- return fallback;
+
+ // Fallback
+ return [{furigana: reading, text: expression}];
}
distributeFuriganaInflected(expression, reading, source) {
diff --git a/test/test-japanese.js b/test/test-japanese.js
index 54186a96..e70698da 100644
--- a/test/test-japanese.js
+++ b/test/test-japanese.js
@@ -334,6 +334,25 @@ function testDistributeFurigana() {
[
{text: '長い間', furigana: 'ながいあいだ'}
]
+ ],
+ // Same/empty reading
+ [
+ ['飼い犬', ''],
+ [
+ {text: '飼い犬', furigana: ''}
+ ]
+ ],
+ [
+ ['かいいぬ', 'かいいぬ'],
+ [
+ {text: 'かいいぬ', furigana: ''}
+ ]
+ ],
+ [
+ ['かいぬ', 'かいぬ'],
+ [
+ {text: 'かいぬ', furigana: ''}
+ ]
]
];