diff options
-rw-r--r-- | docs/templates.md | 577 |
1 files changed, 577 insertions, 0 deletions
diff --git a/docs/templates.md b/docs/templates.md new file mode 100644 index 00000000..1c9081d2 --- /dev/null +++ b/docs/templates.md @@ -0,0 +1,577 @@ +# 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 to its furigana representation. + +<details> + <summary>Syntax:</summary> + + <code>{{#furigana}}<i><definition></i>{{/furigana}}</code> + + * _`definition`_ <br> + The definition to convert. +</details> +<details> + <summary>Example:</summary> + + ```handlebars + {{#furigana}}{{.}}{{/furigana}} + ``` + + Output: + ```html + <ruby>読<rt>よ</rt></ruby>む + ``` + + Preview + <pre><ruby>読<rt>よ</rt></ruby>む</pre> +</details> + + +### `furiganaPlain` + +Converts a definition to its simplified furigana representation. + +<details> + <summary>Syntax:</summary> + + <code>{{#furiganaPlain}}<i><definition></i>{{/furigana}}</code> + + * _`definition`_ <br> + The definition to convert. +</details> +<details> + <summary>Example:</summary> + + ```handlebars + {{~#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> |