:::meta description: The add-ons that come with Tern, in its addons/ folder: math with KaTeX or MathML, code highlighting with highlight.js, diagrams with Mermaid, a search box over a set of notes, and a list of them. ::: ::site-nav # Add-ons {#top} ::toc Tern comes with add-ons in the `addons/` folder next to `tern.js`. Each one is a script [add-on](schema.html#addons): list it in `data-use` on the tern.js tag, or in a [`:::use` block](syntax-blocks.html#use) at the top of the note, with a [theme](schema.html#themes) if you like. **The engine renders no math itself.** It leaves each formula as its TeX, the way a code fence stays plain without [`code.js`](#code). To typeset the math, load a math add-on: [`katex.js`](#katex) for KaTeX, or [`mathml.js`](#mathml) for native MathML. Load one, not both. ```html ``` Several read better in a `:::use` block, one or more per line, which must come first in the note, after `:::meta` at most: ```html :::use themes/nord.css addons/code.js addons/katex.js ::: ``` From jsDelivr, give each add-on the same tag as `tern.js`: `https://cdn.jsdelivr.net/gh/OzkrAC/tern@TAG/addons/code.js`. :::table[Add-ons]{#tbl-addons} | Add-on | What it does | |---|---| | [`katex.js`](#katex) | typesets formulas with KaTeX, to styled HTML with its own fonts | | [`mathml.js`](#mathml) | typesets formulas as native MathML, with Temml, no fonts to load | | [`code.js`](#code) | colours code by its language, with highlight.js, in the theme's colours | | [`mermaid.js`](#mermaid) | draws `mermaid` fences as diagrams, with Mermaid, in the theme's colours | | [`search.js`](#search) | a `::search` box over a set of notes, indexed in the browser or from the index `tern index` writes, each hit linking to its heading or block | | [`notes.js`](#notes) | a `::notes` list of the notes in a folder, from the catalogue `tern index` writes | ::: ## Code highlighting {#code} `code.js` colours the code in every fence that names its language: keywords, strings, comments, numbers, function and type names. The colours come from the page's theme. :::syntax ```html ``` ::: This page loads it, so the fence below is coloured: ```js {lines hl=3} // The nth Fibonacci number. function fib(n) { return n < 2 ? n : fib(n - 1) + fib(n - 2); } ``` ### Which fences {#code-fences} - **A fence that names its language,** by name or by alias: ```` ```js ````, ```` ```python ````, ```` ```tex ````. Titled fences ([listings](elements.html#numbering)) are coloured too. - **Left as they are:** a fence with no language, one marked `text`, `txt`, `plaintext` or `nohighlight`, and one in a language highlight.js does not know, such as `tern`. Inline code is never coloured. - **Line numbers and highlighted lines stay.** `{lines hl=3}` works as it does without the add-on: the coloured text is split back into the lines, and a comment that runs over two lines is coloured on both. - **The text does not change.** The add-on only wraps it in `` elements, so copying code copies the same text. ### Languages {#code-languages} - **With the add-on, 36 languages load at once,** highlight.js's common bundle: bash, c, cpp, csharp, css, diff, go, graphql, ini, java, javascript, json, kotlin, less, lua, makefile, markdown, objectivec, perl, php, php-template, plaintext, python, python-repl, r, ruby, rust, scss, shell, sql, swift, typescript, vbnet, wasm, xml and yaml, with their aliases (`js`, `py`, `sh`, `html` …). - **157 more load the first time a note uses one,** each a small file: latex (`tex`), haskell (`hs`), scala, elixir, julia, matlab, ocaml, dockerfile, nginx, powershell and the rest of [highlight.js's languages](https://highlightjs.readthedocs.io/en/latest/supported-languages.html). - **An alias two languages share is not used:** `ls` is both Lasso and LiveScript, so write `lasso` or `livescript`. ### Colours {#code-colours} The add-on maps highlight.js's classes onto ten [custom properties](schema.html#custom-properties). tern.css sets them for light, dark and print, and every [theme](schema.html#themes) sets its own, after that theme's syntax colours. :::table[Code colours]{#tbl-code-colours} | Property | Colours | |---|---| | `--t-code-comment` | comments, in italics | | `--t-code-keyword` | keywords, tag names | | `--t-code-string` | strings, regular expressions | | `--t-code-number` | numbers, literals such as `true` and `null` | | `--t-code-function` | function names, section titles | | `--t-code-type` | types, class names, built-ins | | `--t-code-variable` | variables, attributes, properties | | `--t-code-meta` | preprocessor lines, doctypes, prompts | | `--t-code-inserted` | added lines in a diff | | `--t-code-deleted` | removed lines in a diff | ::: - **Readable.** Each code colour has at least 4.5:1 contrast against the code background, and 3:1 on a highlighted line (`hl=`), where it sits on the highlight colour; in High contrast, 7:1 and 4.5:1. A theme's original colour that falls short is darkened or lightened until it passes. - **Print** uses tern.css's light colours, as the rest of the page does. - **Your own colours:** set the properties in your CSS, as for any [custom property](schema.html#overriding), or style highlight.js's classes (`.hljs-keyword` …) directly. ```html ``` ### How it loads {#code-loading} - **From jsDelivr.** The add-on asks for highlight.js 11.12.0 as soon as it runs, alongside KaTeX and the other add-ons, pinned with [SRI](publishing.html#csp) hashes. Code shows plain until it arrives, then turns coloured. - **A copy of your own,** for offline use or a strict policy: `?base=` names the folder of `highlight.min.js` and `languages/`, the layout of the npm package `@highlightjs/cdn-assets`. A copy is loaded without SRI. - **Content-Security-Policy.** Allow `https://cdn.jsdelivr.net` in `script-src`, as KaTeX needs, or use a copy. With [`data-nonce`](publishing.html#csp), the add-on's scripts carry the nonce. - **A highlight.js already on the page** is used as it is, with the languages it has. - **If highlight.js does not load,** code stays plain, and the console shows a warning. - **Without the page.** `tern check` and `tern build` run the add-on but do not colour code: a built page is coloured when `tern.js` runs on it, and without JavaScript code shows plain. ### A newer highlight.js {#code-updating} The version and its hashes live in a table in `addons/code.js`. To move to another version, run `node tools/hljs.js VERSION`: it downloads the package from the npm registry once, checks it, and rewrites the table. ## Diagrams {#mermaid} `mermaid.js` draws each fence in the language `mermaid` as a diagram, with [Mermaid](https://mermaid.js.org): flowcharts, sequence, class, state and entity–relationship diagrams, Gantt and pie charts, mind maps, timelines, git graphs and the rest of [Mermaid's diagrams](https://mermaid.js.org/intro/syntax-reference.html). They take the page theme's colours and its sans-serif font. :::syntax ```html ``` ::: This page loads it. This source: ````tern ```mermaid flowchart LR A[Write the note] --> B{Does it parse?} B -- yes --> C[Publish] B -- no --> D[Fix it] D --> A ``` ```` draws this diagram: ```mermaid flowchart LR A[Write the note] --> B{Does it parse?} B -- yes --> C[Publish] B -- no --> D[Fix it] D --> A ``` ### Figures and ids {#mermaid-figures} - **In a figure,** a diagram gets the figure's caption, its number where the vocabulary counts figures, and references. - **An id on the fence,** as in ```` ```mermaid {#id} ````, goes to the diagram, so links land on it; a diagram Mermaid cannot draw gives it back to the fence. The ids inside a drawing (its nodes, markers, styles) are made unique to each placement, so two fences with one source, or a screen and a print copy, never repeat an id. - **A titled fence** (```` ```mermaid[Title] ````) is a [listing](guide.html#listings), as for code. For a diagram, a figure usually reads better. ````tern :::figure[From source to page]{#fig-pipeline} ```mermaid flowchart LR S[source] --> P[parse] --> T[transform] --> E[emit] --> M[mount] ``` ::: @fig-pipeline shows the engine's steps. ```` :::figure[From source to page]{#fig-pipeline} ```mermaid flowchart LR S[source] --> P[parse] --> T[transform] --> E[emit] --> M[mount] ``` ::: @fig-pipeline shows the engine's steps. ### Colours {#mermaid-colours} The add-on sets Mermaid's `base` theme from the page's [custom properties](schema.html#custom-properties), so every [theme](schema.html#themes) has matching diagrams. - **Shapes and lines.** Nodes are `--t-soft` with `--t-muted` borders, lines and arrows `--t-muted`, text `--t-fg`. Notes are `--t-mark`, and critical tasks in a Gantt chart are `--t-error` on `--t-error-bg`. - **Categories:** pie slices, git branches, mind map and timeline sections, the series of an xy chart. These take the theme's accents in turn: `--t-link`, then the [code colours](#code-colours), less any too close to one already taken. Pie slices and branches use the accents themselves; sections use a tint of them, with text in `--t-fg`. - **Light, dark and print.** Mermaid writes the colours into each drawing, so the add-on draws a diagram for the palette in effect, and again when the reader switches between light and dark. Unless the palette is already tern.css's print palette, a diagram is drawn a second time in those print colours, black on white, and that copy is the one printed: a dark theme's and a light theme's alike. - **Your own colours:** set the custom properties, or Mermaid's own theme variables, which win: `window.TERN = {use: {mermaid: {themeVariables: {primaryColor: '#e8f0fe'}}}}`. With a Mermaid theme of its own, such as `?theme=forest`, a diagram keeps Mermaid's colours. ### Options {#mermaid-options} - **Mermaid's settings.** Every option but `base` goes to `mermaid.initialize`: `?look=classic` for Mermaid's earlier look, or `?layout=dagre` for the layout before ELK, Mermaid 12's default. Nested settings go in `window.TERN = {use: {mermaid: {…}}}`. - **One diagram's settings:** a diagram's own `config` front matter, or a `%%{init: …}%%` line, applies to that diagram alone. - **Strict security.** Mermaid runs with `securityLevel: 'strict'`, whatever the add-on's options say: labels cannot hold HTML or scripts, and clicking a node runs no JavaScript. ### How it loads {#mermaid-loading} - **Only where it is needed.** The add-on asks for Mermaid 12.1.0 when a note has a `mermaid` fence. It is one file from jsDelivr, pinned with [SRI](publishing.html#csp): 1.5 MB compressed, 5.5 MB as JavaScript. Each fence shows its source until Mermaid arrives. - **A copy of your own,** for offline use or a strict policy: `?base=` names the folder of `mermaid.min.js`, the `dist/` folder of the npm package `mermaid`. A copy is loaded without SRI. A `window.mermaid` already on the page is used as it is. - **Content-Security-Policy.** Allow `https://cdn.jsdelivr.net` in `script-src`, or use a copy. Mermaid writes inline styles as it draws. With [`data-nonce`](publishing.html#csp), the add-on sets them through the CSSOM and gives its `