# @ffs/highlightjs-fson
A [highlight.js](https://github.com/highlightjs/highlight.js) language
definition for **FSON** — the hand-editable configuration notation used by
the FFS project. FSON is a pragmatic superset of
[JSON5](https://json5.org/) that adds nested block comments, a narrower
bare-key grammar, `--` disabled members, `%include` directives, and
`|`-block multi-line strings.
It colorizes ` ```fson ` fenced code blocks on the web and anywhere
highlight.js runs.
## Install
```bash
npm install @ffs/highlightjs-fson highlight.js
```
## Register and use
```js
import hljs from 'highlight.js';
import fson from '@ffs/highlightjs-fson';
hljs.registerLanguage('fson', fson);
const html = hljs.highlight(source, { language: 'fson' }).value;
// or, for all <pre><code class="language-fson"> blocks on a page:
hljs.highlightAll();
```
CommonJS builds can reach the definition through the default export:
```js
const hljs = require('highlight.js');
hljs.registerLanguage('fson', require('@ffs/highlightjs-fson').default);
```
## CDN (browser)
```html
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<script type="module">
import fson from 'https://cdn.jsdelivr.net/npm/@ffs/highlightjs-fson/src/fson.js';
hljs.registerLanguage('fson', fson);
hljs.highlightAll();
</script>
```
### Self-registering bundle
`scripts/build-browser.sh` produces `dist/fson.min.js` — a minified IIFE
that calls `hljs.registerLanguage('fson', …)` itself. Drop it in after
highlight.js and nothing else is needed:
```html
<script src="/highlight.min.js"></script>
<script src="/fson.min.js"></script> <!-- registers 'fson' on load -->
```
This is what <https://fson.fedem.eu> loads to colour ` ```fson ` blocks.
## What it highlights
| FSON construct | highlight.js scope |
|---|---|
| `//` and nested `/* … */` comments | `comment` |
| bare and quoted keys | `attr` |
| string values, `\|`-block strings | `string` |
| escape sequences (`\n`, `\xHH`, `\uHHHH`, …) | `char.escape` |
| numbers, hex (`0xFF`), `Infinity`, `NaN`, `.5`, `5.` | `number` |
| `true` / `false` / `null` | `literal` |
| `%include`, `as` | `keyword` |
| `--` disabled members / directives / `\|`-lines | `deletion` |
The bare-key grammar deliberately follows FSON's narrower `name`
production, **not** JSON5's `IdentifierName`, so keys like `$foo`, `_x`,
`name_`, or `a__b` are treated as ordinary text (they must be quoted to be
keys in FSON). The exact production is:
```
name = [A-Za-z] ( _? [A-Za-z0-9] )*
```
## Scope note
An FSON `|`-block is highlighted as a single string. Markdown embedded
inside such a block is **not** separately highlighted — this is an
intentional scope decision, not a limitation.
## Test
```bash
npm install
npm test # runs the highlight.js markup fixtures under test/markup/
```
The grammar is validated against the real FSON files in the project's
`corpus/fson/` directory.
## License
MIT