# Parsing

> Markdown to a document, anywhere.

## Parser

`@humanonlyweb/writer/parse` has no Vue and no DOM: it runs on the server, in a worker, in a script.

```ts
import { createParser } from "@humanonlyweb/writer/parse";

const parse = createParser({ highlight: true, toc: true });
const document = await parse(markdown);
document.meta.toc; // { links: [{ id, text, depth, children }] }
```

`parse` is `createParser()` with the defaults. Use the same options everywhere you parse: the Nuxt module's `parser`, `createWriter({ parser })` and the server.

## Options

| Option      | Default | What it does                                                                                                                                               |
| ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `footnotes` | `true`  | `[^1]` footnotes. An object sets `label` and `backRef`.                                                                                                    |
| `highlight` | `false` | Highlights fenced code with [rangi](https://comark.dev/plugins/built-in/rangi). An object sets `theme`, `lineNumbers`. Loads only for documents with code. |
| `toc`       | `false` | Table of contents in `meta.toc`. An object sets `depth`.                                                                                                   |
| `linkify`   | `true`  | URL-like text becomes links.                                                                                                                               |
| `plugins`   | `[]`    | Other Comark plugins, e.g. `comark/plugins/shiki`. They run before sanitizing. Not in `nuxt.config`: they aren't serializable, so parse on the server.     |

## Syntax

CommonMark and GFM (tables, task lists, strikethrough, autolinks), frontmatter, footnotes, GitHub alerts, [blocks](/blocks) and `{.class #id key="value"}` attributes. Raw HTML is text.

A blank line starts a paragraph; a `\` at the end of a line breaks it. The editor's Enter and Shift+Enter write those for you.

## Dark mode code

rangi colours code inline for its light theme and puts the dark one in `--shiki-dark`:

```css
@media (prefers-color-scheme: dark) {
  .shiki span {
    color: var(--shiki-dark) !important;
  }
}
```

This site does exactly that.
