Сохранение состояния

Библиотека Marked в JavaScript представляет собой мощный парсер Markdown, который преобразует текст в HTML. Для начала работы необходимо установить пакет через npm:

npm install marked

После установки подключение осуществляется стандартным способом:

import { marked } from 'marked';

Базовое преобразование Markdown в HTML выполняется функцией marked.parse:

const markdownText = "# Заголовок 1\n\nТекст с **жирным** форматированием";
const html = marked.parse(markdownText);
console.log(html);

Результат будет:

Заголовок 1

Текст с жирным форматированием

Настройка рендеринга

Marked позволяет полностью контролировать процесс преобразования Markdown в HTML через объект Renderer. Это особенно важно при сохранении состояния, когда нужно управлять отображением и поведением отдельных элементов.

const renderer = {
  heading(text, level) {
    return `${text}`;
  },
  link(href, title, text) {
    return `${text}`;
  }
};

const htmlCustom = marked.parse(markdownText, { renderer });

Использование собственного рендерера позволяет сохранять консистентность стилей при повторном рендеринге Markdown, что критично для сохранения состояния интерфейса.

Опции конфигурации

Marked поддерживает множество опций, влияющих на парсинг и генерацию HTML. Основные:

  • gfm (boolean) — включение GitHub Flavored Markdown (по умолчанию true).
  • breaks (boolean) — интерпретация переносов строк как
    .
  • sanitize (boolean) — удаление опасных HTML-тегов.
  • mangle (boolean) — защита email-адресов от спама.
  • headerIds (boolean) — генерация идентификаторов для заголовков.

Пример использования:

const htmlSafe = marked.parse(markdownText, {
  gfm: true,
  breaks: true,
  sanitize: true
});

Эти параметры критичны для сохранения состояния, так как они обеспечивают предсказуемое поведение при повторном рендеринге.

Потоковое рендеринг и сохранение состояния

Для приложений с динамическим контентом важно не только преобразовать Markdown в HTML один раз, но и поддерживать состояние между обновлениями. Marked предоставляет возможности для ленивого и потокового рендеринга через Lexer и Parser.

const tokens = marked.lexer(markdownText); // Разбор текста на токены
const htmlFromTokens = marked.parser(tokens); // Генерация HTML из токенов

Такой подход позволяет:

  • Сохранять промежуточное состояние токенов.
  • Обновлять только изменённые участки Markdown.
  • Минимизировать повторный рендеринг всего документа.

События и кастомизация

Marked можно расширять через хуки для обработки определённых типов контента, что упрощает управление состоянием. Например, можно добавлять классы к элементам, отслеживать вставленные ссылки или изображения:

marked.use({
  renderer: {
    listitem(text) {
      return `
  • ${text}
  • `; } } });

    Это позволяет сохранять визуальное и функциональное состояние элементов при динамических изменениях документа.

    Асинхронная обработка

    Для больших документов и интеграции с внешними источниками Markdown Marked поддерживает асинхронную обработку:

    import fs from 'fs/promises';
    
    async function renderMarkdownFile(path) {
      const content = await fs.readFile(path, 'utf-8');
      const html = await marked.parse(content);
      return html;
    }

    Асинхронный рендеринг помогает управлять состоянием, не блокируя основной поток выполнения и обеспечивая плавное обновление интерфейса.

    Сохранение пользовательских настроек

    Marked позволяет сохранять состояние через конфигурацию и токены. Например, можно хранить текущие настройки рендерера, массив токенов и пользовательские стили, чтобы при следующем открытии документа восстановить прежний вид и структуру. Это особенно важно для редакторов Markdown, где требуется постоянное состояние:

    const state = {
      tokens: marked.lexer(markdownText),
      rendererConfig: { headingLevelOffset: 1 }
    };
    const htmlRestored = marked.parser(state.tokens, { renderer: state.rendererConfig });

    Такой подход обеспечивает консистентность интерфейса и предотвращает потерю данных при редактировании и обновлениях.