Code View

fson / @ffs-highlightjs-fson / package / README.md
Preview
# @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