# Writing a guide
A guide is a `.md` file under `contents/pages/guides`, and nothing else. No php, no html: what you read in
the file is what the page shows, which is the whole point — a guide that needs the site to run before it
can be read is a guide nobody reads in a pull request.
## Where a guide goes
```
contents/pages/guides/<section>/<NN>-<name>.md
```
The section folder is one of the pages listed in `guides/index.json`. Inside it:
- **The first heading is the title in the tree.** The filename only has to sort, so it never shows.
- **A leading number puts the section in reading order** (`10-`, `20-`…) instead of alphabetical order.
Leave gaps,
so a guide can be inserted later without renumbering the lot.
- A sub-folder becomes a branch of the tree, labelled after the folder's name.
## Never copy a reference
Anything that describes how the code behaves belongs next to that code, in its package's `docs/` folder,
and a guide pulls it in:
```md
<!-- @include {MMO\client}/../docs/JHS.md -->
```
The path is resolved by `\MMO\filename()`. `{MMO\client}` is the client package's `src` folder, so
`{MMO\client}/../docs/X.md` reads this package's reference and `{MMO\client}/../../core/docs/X.md` reads
`mmo.core`'s. A plain relative path is read next to the guide itself.
Do **not** anchor on `{root}` or `{basepath}`: a package is served from its own root through a rewrite,
which moves both of them depending on whether the code is running under the web server or the shell.
So a guide is usually an orientation — what this is for, what to watch out for, what to read next — and
then one include. That way a fix to the reference fixes the guide, and the two can never drift.
## What the renderer supports
`<mmo-markdown>` implements a subset. These work:
| | |
|---|---|
| headings | `#` to `######` |
| emphasis | `*italic*`, `**bold**`, `***both***` |
| inline | `` `code` ``, `~sub~`, `~~strikethrough~~`, `^sup^`, `==highlight==` |
| lists | `-` and `1.`, nested by one tab |
| quotes | `>`, which is what a note or a warning looks like here |
| tables | `\|a\|b\|` with an optional `\|---\|:-:\|` alignment row |
| rules | `---` |
| links | `[text](url)`, reference links, and bare urls |
| code | fenced with three backticks, or indented by four spaces |
These do **not**: footnotes, task lists, definition lists, `:emoji:` shortcodes, and **raw html** — the
parser escapes every `<` it finds in text, so a `<strong>` in a guide shows up as `<strong>`. Use markdown.
Two more limits worth knowing, because both fail silently:
- **Inline markup does not nest.** Code inside bold, or bold inside a link, comes out with its markers
showing. Put the code span beside the bold run, never inside it.
- **An inline span must not cross a line break.** The parser reads one line at a time, so a `**bold**`
whose closing marker is on the next line is left as literal asterisks. Rewrap instead.
### An `html` fence is live
A fenced block whose language is `html` is rendered by `<mmo-code language="html">`, which shows a
**live preview** of the markup with a toggle back to the source. That is exactly what you want for an
example of an element:
```html
<mmo-icon name="house">Home</mmo-icon>
```
It is also why a `.jhs` source belongs in a `jhs` fence instead — a `<script>` inside an `html` fence is
markup that will run.
## Linking to another guide
A guide is rendered on its section's page, so a relative link reaches any other section:
```md
[Requirements](installation?guide=10-requirements.md)
[Tokens](../styles/tokens)
```
## Style
- One idea per heading, and respect the hierarchy: no `###` directly under a `#`.
- Say what the thing is for before saying how it is configured.
- Bold the term being defined, not the sentence around it.
- If you write "should be X", check that it is X. A guide that is wrong costs more than a guide that is
missing.
# Custom Element — How to write its documentation
## The short version
**You document an element in the element.** The jsdoc of its class is its reference: the compiler reads
it and emits a `documentation()` method next to the element, and a page shows it with one tag:
```html
<mmo-element-doc element="mmo-icon"></mmo-element-doc>
```
Nothing is written twice, so nothing can drift. A page that repeats what the element declares is a page
that will be wrong in six months.
---
## What the compiler reads
`MMO\client\JHSCompiler` extracts the class jsdoc when it compiles a `.jhs` file. Four tags on the class
comment, plus the ordinary jsdoc of the members:
| in the element | on the page |
|---|---|
| the sentence at the top of the class comment | the description under the title |
| `@attr name - what it does` | a row of **Attributes**, and a control in the configurator |
| `@css class - what it changes` | a row of **Classes**, and a checkbox |
| `@slot name - what goes in it` | a row of **Slots**, and a text area |
| the comment above a method, with `@param` / `@return` | a row of **Methods** |
| the comment above a getter, with `@return {type}` | a row of **Properties** |
```js
/**
* Icon element to display an icon.
*
* @class Icon
* @attr name - the name of the icon
* @css round - make the icon round
* @slot - a label, shown next to the glyph
*/
class Icon {
/**
* Whether this block can show a live preview instead of its source.
* @return {boolean} true if this block's language has a renderable preview
*/
isHtml() {…}
}
```
Two things that bite:
- **Write a sentence, not only a return type.** A member documented by its `@return` alone has no
description, and the reference shows an empty cell.
- **A section banner must not open as jsdoc.** `/** ---- Websocket ---- */` is a jsdoc comment as far as
the compiler is concerned. Use `/* ---- */`.
A slot the element has but nobody documented still appears in the reference, with an empty description:
the sheet reads the shadow root as well as the jsdoc, so a missing sentence is visible rather than
invisible.
---
## The page
The documentation pages live in `demo/www/contents/pages/customElements`, one `.phtml` per element, named
after it without the `mmo-` prefix, in the sub-folder its source sits in (`elements`, `inputs`, `layout`,
`modules`, `tools`). A page is prose plus the sheet:
```html
<article>
<h1>mmo-progress</h1>
<p>What it is, in one or two sentences.</p>
<h2>Usage</h2>
<p>When to reach for it, and what it expects.</p>
<h2>Examples</h2>
<mmo-code language="html">
<mmo-progress value="0.5">progress</mmo-progress>
</mmo-code>
<h2>Reference</h2>
<mmo-element-doc element="mmo-progress">
<script type="application/json" slot="preset">
{"attributes": {"value": {"value": "0.64", "type": "number"}},
"slots": {"": "Import en cours"}}
</script>
</mmo-element-doc>
<h2>Tags</h2>
`#custom element` `#progress`
</article>
```
What belongs in the page, and only there:
- **prose**: what the element is for, and what it expects of the page around it;
- **examples**: `<mmo-code language="html">` renders a live preview of what it shows, so an example is
never out of date either;
- **anything the element cannot know**: how it fits a workflow, what a project should do with it.
What never belongs in the page: a table of attributes, classes, slots or methods. That is the element's
job, and the sheet's.
### The preset
The `preset` slot gives the configurator a useful starting point — an element with no attributes set
often previews as nothing at all:
| key | what it does |
|---|---|
| `attributes` | per name: `value` to start with, `values` to offer as a list, `type` (`number`), `on` to switch a valueless attribute on |
| `classes` | the classes already checked |
| `slots` | the starting content of each slot, `""` being the default one |
| `ground` | the preview's background: `surface`, `bg` or `ink` |
`class="compact"` on the sheet hides the configurator, for a reference-only page.
---
## Checking your work
The sheet shows exactly what the element declares, so read the page you just wrote: an empty
description, a slot with no sentence or a missing method is the element's jsdoc asking to be finished.