nuckty
EN
Все разделы →

Markdown

Текст страниц пишется на Markdown. Движок преобразует Markdown в BEMTree — ту же модель данных, из которой собирает вёрстку страницы и обёртку документа HTML.

Markdown разбирает связка remark/unified: сначала micromark сканирует текст, затем remark строит mdast — типизированное дерево Markdown. Почему не markdown-it, объясняет решение о движке Markdown.

Что поддерживает ядро

Ядро поддерживает CommonMark, а также возможности GFM: таблицы, зачёркивание ~~текст~~, списки задач (- [x]) и автоматические ссылки. Оно также разбирает директивы :::name для markdown-расширений. Мост mdast → BEMJSON преобразует разобранные узлы в BEMTree.

Иерархические якоря

Движок назначает заголовкам идентификаторы по правилу иерархических якорей. Если раздел вложен, идентификатор составной:

# Шины              → id="шины"
## Зимние            → id="шины-зимние"
### Шипованные       → id="шины-зимние-шипованные"

Кириллица сохраняется в идентификаторах — без транслитерации и без кодирования. Нумерованный префикс (1. , 1.2. ) убирается из видимого заголовка и якоря; косую черту заменяет дефис. Точки в остальном тексте сохраняются: # Версия 2.4.3. получает якорь версия-2.4.3.. Ссылаться на якорь можно прямо кириллицей.

Собственный идентификатор задают суффиксом {#id} в обычном тексте в конце заголовка, например # **Title** {#custom}. Суффикс удаляется из видимого текста; внутри кода, ссылки или выделения он остаётся обычным содержимым.

Перекрёстные ссылки

Авторы пишут обычные ссылки в Markdown на файлы .md:

См. [модель данных](../how/bemjson.ru.md).

Движок преобразует путь в адрес по карте md2url, построенной из карты сайта. Можно сослаться и на якорь другого документа:

См. [шипы](../free/tyres.md#шины-зимние-шипованные).

Движок превращает якорь в итоговый иерархический идентификатор целевой страницы. Ссылка на отсутствующий документ .md прерывает сборку. Неизвестные фрагменты сохраняются: шаблон страницы может добавлять собственные идентификаторы. Автору не нужно знать итоговый адрес — достаточно пути к файлу.

Изображения

Ссылка на изображение в Markdown — логический адрес. По общему для Markdown и CSS файлу image-mapping.json движок находит хэшированный адрес семейства изображения. Подготовленные варианты AVIF/WebP копирует стадия изображений, а формат выбирает сервер. Подробнее — изображения в результате сборки.

![Подпись](images/tyre.png)   → <img class=article__image src=/_ia1b2c3d4e5f6a7b8 alt="Подпись">

Автор указывает одну ссылку, сервер отдаёт подходящий формат.

Типографика

Типографика русского текста — это markdown-расширение: до сборки HTML оно проходит по дереву Markdown и не даёт тире отрываться от слова — ставит неразрывный пробел перед длинным тире и обычный после. Узлы кода расширение не трогает.

Поскольку это расширение, а не часть ядра, англоязычному сайту оно не нужно — его просто не подключают.

Конструкции markdown-разметки — расширения

Галерея, сетка, выноска и видео в ядро не входят. Ядро не знает конкретных конструкций :::gallery или :::callout. Их добавляют markdown-расширения: обработчик преобразует конструкцию в узлы BEMJSON нужного блока.

:::gallery
![a](1.png) ![b](2.png)
:::

Здесь :::gallery — синтаксис markdown-расширения. Без расширения движок убирает оболочку директивы и обрабатывает Markdown внутри неё как обычно. См. каталог markdown-расширений.

Встроенный HTML

Встроенный HTML из Markdown (например, <span> в тексте) сохраняется как raw: сериализатор не экранирует и не минимизирует его. Парсер не очищает HTML и не проверяет структуру документа. При этом отдельный проход переписывает логические пути в img src по карте изображений. Передавайте только доверенный HTML.

Карта изображений меняет значения настоящих атрибутов img src, с кавычками или без них. Текст, похожий на изображение, внутри атрибутов, комментариев, скриптов, стилей и элементов с буквальным содержимым сохраняется.

Пробелы разобранного текста возле встроенного HTML и ссылок сохраняются: в Hello <em>world</em> остаётся разделяющий пробел, а в x[link](/target) новый пробел не добавляется. Типографика остаётся опциональной.

Программный вызов

При сборке ссылки и пути к изображениям отсчитываются от каталога текущего файла Markdown внутри корня контента. Имя корневого каталога на разрешение путей не влияет. При самостоятельном вызове createMarkdown передайте в sourceFile путь к файлу относительно корня контента; при необходимости сохраните inputPath для диагностики и существующих интеграций.

import { createMarkdown } from 'nuckty';

const { tree } = createMarkdown({
    sourceFile: 'guide/start.md',
    inputPath: './content/guide/start.md',
    md2url: { 'index.md': '/' },
    imageMapping: { 'images/logo.png': '_i1234567890123456' },
}).render('[Home](../index.md) ![Logo](../images/logo.png)');