008ffdb6bf
* Update japanese.js tests * Simplify fallback/early exit * Add overloads to furigana and furiganaPlain handlebars helper functions * Expose unique expression/reading arrays (and subsequently counts) * Add {frequencies} marker
590 lines
14 KiB
Markdown
590 lines
14 KiB
Markdown
# Templates
|
|
|
|
## Helpers
|
|
|
|
Yomichan supports several custom Handlebars helpers for rendering templates.
|
|
The source code for these templates can be found [here](../ext/bg/js/template-renderer.js).
|
|
|
|
|
|
### `dumpObject`
|
|
|
|
Converts an object to a pretty-printed JSON string.
|
|
This function can be helpful for debugging values when creating templates.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#dumpObject}}<i><object></i>{{/dumpObject}}</code>
|
|
|
|
* _`object`_ <br>
|
|
The object to convert.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
<pre>{{#dumpObject}}{{.}}{{/dumpObject}}</pre>
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
<pre>{
|
|
"key": "value"
|
|
}</pre>
|
|
```
|
|
|
|
Preview:
|
|
```html
|
|
{
|
|
"key": "value"
|
|
}
|
|
```
|
|
</details>
|
|
|
|
|
|
### `furigana`
|
|
|
|
Converts a definition or expression/reading pair to its furigana representation.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#furigana}}<i><definition></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:
|
|
```html
|
|
<ruby>読<rt>よ</rt></ruby>む
|
|
```
|
|
|
|
Preview
|
|
<pre><ruby>読<rt>よ</rt></ruby>む</pre>
|
|
</details>
|
|
|
|
|
|
### `furiganaPlain`
|
|
|
|
Converts a definition or expression/reading pair to its simplified furigana representation.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#furiganaPlain}}<i><definition></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:
|
|
```html
|
|
読[よ]む
|
|
```
|
|
</details>
|
|
|
|
|
|
### `multiLine`
|
|
|
|
Replaces newline characters with a forced HTML line break `<br>`.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#multiLine}}<i>text with multiple lines</i>{{/multiLine}}</code>
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#kanjiLinks~}}
|
|
some
|
|
multiline
|
|
text
|
|
{{~/kanjiLinks}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
some<br>multiline<br>text
|
|
```
|
|
|
|
Preview:
|
|
<pre>some<br>multiline<br>text</pre>
|
|
</details>
|
|
|
|
|
|
### `regexReplace`
|
|
|
|
Uses a [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) to replace a pattern with the specified text.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#regexReplace <i>regex</i> <i>replacement</i> <i>[flags]</i>}}<i>text-to-modify</i>{{/regexReplace}}</code>
|
|
|
|
* _`regex`_ <br>
|
|
The raw string used to create the regular expression. This value is passed to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
|
|
* _`replacement`_ <br>
|
|
The text used to replace pattern matches. This supports the standard [special capture group replacements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter) as supported by the web browser.
|
|
* _`flags`_ _(optional)_ <br>
|
|
Optional flags to pass to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
|
|
* _`text-to-modify`_ <br>
|
|
The text that the regular expression is applied to.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#regexReplace "\(([^)]*)\)" "$1" "g"~}}Here is (some) (text) (in) (parentheses){{~/regexReplace}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
Here is some text in parentheses
|
|
```
|
|
</details>
|
|
|
|
|
|
### `regexMatch`
|
|
|
|
Uses a [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) to return only the content that matches the pattern.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#regexMatch <i>regex</i> <i>[flags]</i>}}<i>text-to-modify</i>{{/regexMatch}}</code>
|
|
|
|
* _`regex`_ <br>
|
|
The raw string used to create the regular expression. This value is passed to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
|
|
* _`flags`_ _(optional)_ <br>
|
|
Optional flags to pass to the [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) constructor.
|
|
* _`text-to-modify`_ <br>
|
|
The text that the regular expression is applied to.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#regexMatch "\(([^)]*)\)" "g"~}}Here is (some) (text) (in) (parentheses){{~/regexMatch}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
(some)(text)(in)(parentheses)
|
|
```
|
|
</details>
|
|
|
|
|
|
### `mergeTags`
|
|
|
|
Creates a set of all unique tags for the definition and returns a text representation of the tags separated by commas.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#mergeTags <i>definition</i> <i>isGroupMode</i> <i>isMergeMode</i>}}{{/mergeTags}}</code>
|
|
|
|
* _`definition`_ <br>
|
|
The root definition object.
|
|
* _`isGroupMode`_ _(optional)_ <br>
|
|
Whether or not the display mode is the 'group' mode.
|
|
* _`isMergeMode`_ <br>
|
|
Whether or not the display mode is the 'merge' mode.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{~#mergeTags definition group merge}}{{/mergeTags~}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
v5m, vt, JMdict (English)
|
|
```
|
|
</details>
|
|
|
|
|
|
### `eachUpTo`
|
|
|
|
Similar to the built-in `each` function, but iterates up to a maximum count.
|
|
If the iterable is falsy or empty, the `else` condition will be used.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#eachUpTo <i>iterable</i> <i>maxCount</i>}}<i>(modification)</i>{{else}}<i>(else-modification)</i>{{/eachUpTo}}</code>
|
|
|
|
* _`iterable`_ <br>
|
|
The object that should be looped over. A JavaScript [`for...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) loop is used, so the object only needs to be iterable.
|
|
* _`maxCount`_ _(optional)_ <br>
|
|
The maximum number of entries to loop over.
|
|
* _`modification`_ <br>
|
|
The template used to modify the value. The context is changed to the current item of iteration.
|
|
* _`else-modification`_ <br>
|
|
The template used in case the iterable is falsy or empty. The context is unchanged.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{~#eachUpTo someArray 5}}{{{.}}}<br>{{else}}Empty{{/mergeTags~}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
someArray[0]<br>someArray[1]<br>someArray[2]<br>someArray[3]<br>someArray[4]<br>
|
|
```
|
|
|
|
Preview:
|
|
<pre>someArray[0]<br>someArray[1]<br>someArray[2]<br>someArray[3]<br>someArray[4]<br></pre>
|
|
</details>
|
|
|
|
|
|
### `spread`
|
|
|
|
Uses the JavaScript [spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) operator to convert one or more iterables into a single array.
|
|
This allows it to be used similar to an [`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) operation.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#spread <i>iterable1</i> <i>iterable2</i> <i>...</i> <i>iterableN</i>}}{{/spread}}</code>
|
|
|
|
* _`iterableN`_ <br>
|
|
A variable amount of iterable objects to combine into a single array.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#each (spread array1 array2)}}{{{.}}}<br>{{/each}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
array1[0]<br>array1[1]<br>array2[0]<br>array2[1]<br>
|
|
```
|
|
|
|
Preview:
|
|
<pre>array1[0]<br>array1[1]<br>array2[0]<br>array2[1]<br></pre>
|
|
</details>
|
|
|
|
|
|
### `op`
|
|
|
|
Performs a simple operation on one, two, or three arguments. The operations available are:
|
|
|
|
* Unary operators: `+`, `-`, `~`, `!`
|
|
* Binary operators: `+`, `-`, `/`, `*`, `%`, `**`, `==`, `!=`, `===`, `!==`, `<`, `<=`, `>`, `>=`, `<<`, `>>`, `>>>`, `&`, `|`, `^`, `&&`, `||`
|
|
* Ternary operators: `?:`
|
|
|
|
If an unknown operator is specified, the `undefined` value is returned.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#op <i>operator</i> <i>operand1</i> <i>[operand2]</i> <i>[operand3]</i>}}{{/op}}</code>
|
|
|
|
* _`operator`_ <br>
|
|
One of the unary, binary, or ternary operators.
|
|
* _`operand1`_ <br>
|
|
The first operand of the operation.
|
|
* _`operand2`_ _(Optional)_<br>
|
|
The second operand of the operation.
|
|
* _`operand3`_ _(Optional)_<br>
|
|
The third operand of the operation.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#if (op "===" value1 value2)}}Values are equal{{/op~}}<br>
|
|
{{~#op "-" value1}}{{/op~}}<br>
|
|
{{~#op "?:" value1 "a" "b"}}{{/op}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
Values are equal<br>-32<br>a
|
|
```
|
|
|
|
Preview:
|
|
<pre>Values are equal<br>-32<br>a</pre>
|
|
</details>
|
|
|
|
|
|
### `get`
|
|
|
|
Gets a value from the custom state stack.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#get <i>name</i>}}{{/get}}</code>
|
|
|
|
* _`name`_ <br>
|
|
The name of the variable to get.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#get "some-text"}}{{/get}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
This is the value of some-text!
|
|
```
|
|
</details>
|
|
|
|
|
|
### `set`
|
|
|
|
Assigns a value to the custom state stack.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#set <i>name</i>}}<i>value</i>{{/get}}</code><br>
|
|
<code>{{#set <i>name</i> <i>value</i>}}{{/get}}</code><br>
|
|
|
|
* _`name`_ <br>
|
|
The name of the variable to assign.
|
|
* _`value`_ <br>
|
|
The value of the variable.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#set "some-text"}}This is the value of some-text!{{/set~}}
|
|
{{~#set "some-number" 32}}{{/set}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
```
|
|
</details>
|
|
|
|
|
|
### `scope`
|
|
|
|
Pushes a new variable scope to the custom state stack.
|
|
Variable assignments are applied to the most recent scope,
|
|
and variable lookups will start from the most recent scope and work backwards until a value is found.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#scope}}<i>content</i>{{/scope}}</code>
|
|
|
|
* _`name`_ <br>
|
|
The name of the variable to assign.
|
|
* _`value`_ <br>
|
|
The value of the variable.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{~#set "key" 32}}{{/set~}}
|
|
{{~#get "key"}}{{/get~}},
|
|
{{~#scope~}}
|
|
{{~#get "key"}}{{/get~}},
|
|
{{~#set "key" 64}}{{/set~}}
|
|
{{~#get "key"}}{{/get~}},
|
|
{{~/scope~}}
|
|
{{~#get "key"}}{{/get~}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
32,32,64,32
|
|
```
|
|
</details>
|
|
|
|
|
|
### `property`
|
|
|
|
Repeatedly gets a property of an object.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#property <i>object</i> <i>property1</i> <i>property2</i> <i>...</i> <i>propertyN</i>}}{{/property}}</code>
|
|
|
|
* _`object`_ <br>
|
|
The initial object to use.
|
|
* _`propertyN`_ <br>
|
|
A chain of property names to get on the object.
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{property someObject "field" 0 "toString"}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
function toString() { [native code] }
|
|
```
|
|
</details>
|
|
|
|
|
|
### `noop`
|
|
|
|
No-op. Returns the inner contents of the template.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#noop}}<i>content</i>{{/noop}}</code>
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{noop}}Unchanged content{{/noop}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
Unchanged content
|
|
```
|
|
</details>
|
|
|
|
|
|
### `isMoraPitchHigh`
|
|
|
|
Returns whether or not a mora will have a high pitch, given the index of the mora and the position of the downstep.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#isMoraPitchHigh <i>index</i> <i>position</i>}}{{/isMoraPitchHigh}}</code>
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#if (isMoraPitchHigh 1 2)}}High pitch{{else}}Low pitch{{/if}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
High pitch
|
|
```
|
|
</details>
|
|
|
|
|
|
### `getKanaMorae`
|
|
|
|
Returns an array of the mora for a kana string.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#getKanaMorae <i>kana-string</i>}}{{/getKanaMorae}}</code>
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#each (getKanaMorae "よみちゃん")}}{{{.}}}<br>{{/each}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
よ<br>み<br>ちゃ<br>ん<br>
|
|
```
|
|
|
|
Preview:
|
|
<pre>よ<br>み<br>ちゃ<br>ん<br></pre>
|
|
</details>
|
|
|
|
|
|
## Legacy Helpers
|
|
|
|
Yomichan has historically used Handlebars templates to generate the HTML used on the search page and results popup.
|
|
To simplify the and improve Yomichan's capabilities, the HTML elements are now generated directly using a different process.
|
|
|
|
As such, there are several leftover Handlebars helpers that do not have much utility for Anki templates, but are kept for compatibility purposes.
|
|
|
|
|
|
### `kanjiLinks`
|
|
|
|
Replaces kanji characters in the text with linkified versions.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#kanjiLinks}}<i>text</i>{{/kanjiLinks}}</code>
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#kanjiLinks}}読む{{/kanjiLinks}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
<a href="#" class="kanji-link">読</a>む
|
|
```
|
|
|
|
Preview:
|
|
<pre><a href="#" class="kanji-link">読</a>む</pre>
|
|
</details>
|
|
|
|
|
|
### `sanitizeCssClass`
|
|
|
|
Sanitizes text so it can be used as a CSS class name.
|
|
|
|
<details>
|
|
<summary>Syntax:</summary>
|
|
|
|
<code>{{#sanitizeCssClass}}<i>text</i>{{/sanitizeCssClass}}</code>
|
|
</details>
|
|
<details>
|
|
<summary>Example:</summary>
|
|
|
|
```handlebars
|
|
{{#sanitizeCssClass}}some text with many types of characters !@#$%^ 読む{{/sanitizeCssClass}}
|
|
```
|
|
|
|
Output:
|
|
```html
|
|
some_text_with_many_types_of_characters________読む
|
|
```
|
|
</details>
|