# @ffs/highlightjs-ffsmd
A [highlight.js](https://github.com/highlightjs/highlight.js) language
definition for **FFS-MD** — the FFS in-house Markdown dialect. FFS-MD is a
CommonMark-ish base **plus** FFS additions: a top-of-file front-matter
block, the `[IMAGE:…]` / `[VIDEO: …]` / `[SVG: …]` / `[LIST:…]` block
directives, Confluence-style status marks, `:emoji:` shortcodes, and
footnotes / reference links.
It colorizes ` ```ffsmd ` fenced code blocks and FFS content `.md` files.
## Install
```bash
npm install @ffs/highlightjs-ffsmd highlight.js
# optional — enables real FSON highlighting inside ```fson fences:
npm install @ffs/highlightjs-fson
```
## Register and use
```js
import hljs from 'highlight.js';
import ffsmd from '@ffs/highlightjs-ffsmd';
// optional: register FSON first so ```fson fenced blocks are highlighted
import fson from '@ffs/highlightjs-fson';
hljs.registerLanguage('fson', fson);
hljs.registerLanguage('ffsmd', ffsmd);
const html = hljs.highlight(source, { language: 'ffsmd' }).value;
// or, for all <pre><code class="language-ffsmd"> blocks:
hljs.highlightAll();
```
CommonJS builds reach the definition through the default export:
```js
const hljs = require('highlight.js');
hljs.registerLanguage('ffsmd', require('@ffs/highlightjs-ffsmd').default);
```
## What it highlights
Standard Markdown (headings, emphasis, lists, task lists, blockquotes,
GFM tables, fenced code, horizontal rules) is handled by delegating to
highlight.js's built-in `markdown` grammar. On top of that, FFS-MD adds:
| FFS construct | scope |
|---|---|
| top-of-file front-matter `---` block | `meta` |
| front-matter keys | `attr` |
| front-matter values (dates, arrays, booleans, strings) | `number` / `string` / `literal` |
| `[IMAGE:…]` `[VIDEO: …]` `[SVG: …]` `[LIST:…]` directives | `meta` (path `string`, `\|`/`,` `punctuation`, keywords `keyword`) |
| status marks `(/) (x) (!) (?) (y) (n) (on) (off)` | `symbol` |
| emoji shortcodes `:name:` (curated + ISO country flags) | `symbol` |
| footnote ref `[^label]` and def `[^label]:` | `symbol` |
| fenced-code info-string (` ```fson `, ` ```cpp `, …) | `attr` |
### Prefix precision
The directive prefixes are matched exactly, matching the renderer:
`[IMAGE:` has **no** space, while `[VIDEO: ` **has** a trailing space.
Status marks match only the closed literal set — an arbitrary `(word)` is
left as plain text.
### Fenced-code injection
A ` ```fson ` block delegates to the FSON grammar (when
`@ffs/highlightjs-fson` is registered) and a ` ```cpp ` block delegates to
highlight.js's C++ grammar. Other tagged fences keep their info-string
visible as `attr`. If the FSON grammar is not registered, a ` ```fson `
block simply renders as plain text — no error.
> Note: MD→FSON embedding (Markdown highlighted *inside* an FSON `\|`-block
> string) is intentionally out of scope; that boundary lives on the FSON
> side.
## Test
```bash
npm install
npm test # runs the highlight.js markup fixtures under test/markup/
```
The grammar is validated against the real FFS content files in the
project's `corpus/ffsmd/` directory — including a German-language post with
many `[IMAGE:…]` directives that exercise empty (`||`) and multi-field
forms.
## License
MIT