Работа с TypeScript

Для начала необходимо установить библиотеку через npm или yarn:

npm install markdown-it

или

yarn add markdown-it

Чтобы использовать библиотеку в TypeScript, важно правильно подключить типы:

npm install --save-dev @types/markdown-it

После установки можно создать экземпляр Markdown-it с указанием настроек:

import MarkdownIt from "markdown-it";

const md = new MarkdownIt({
    html: true,             // Разрешает использование HTML-тегов внутри Markdown
    linkify: true,          // Автоматически превращает URL в ссылки
    typographer: true       // Включает типографические улучшения
});

Основные методы

Метод render

Метод render принимает строку Markdown и возвращает строку HTML:

const markdownText = `
# Заголовок 1
**Жирный текст**
`;

const result = md.render(markdownText);
console.log(result);

Метод renderInline

renderInline используется для рендеринга текста без автоматического добавления тегов <p>:

const inlineText = "**Пример текста** без абзаца";
const resultInline = md.renderInline(inlineText);
console.log(resultInline); // <strong>Пример текста</strong> без абзаца

Настройка плагинов

Markdown-it поддерживает подключение плагинов, что значительно расширяет возможности библиотеки. Пример подключения плагина markdown-it-anchor для генерации якорей в заголовках:

import markdownItAnchor from "markdown-it-anchor";

md.use(markdownItAnchor, {
    permalink: true,
    permalinkSymbol: "#"
});

Другие популярные плагины:

  • markdown-it-footnote — добавление сносок;
  • markdown-it-deflist — списки определений;
  • markdown-it-abbr — сокращения и аббревиатуры.

Подключение плагина в TypeScript идентично, важно корректно типизировать его:

import MarkdownIt from "markdown-it";
import markdownItFootnote from "markdown-it-footnote";

const md = new MarkdownIt();
md.use(markdownItFootnote);

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

Markdown-it позволяет создавать собственные правила для обработки текста. Основные точки расширения:

  • Block rules — обработка блочных элементов;
  • Inline rules — обработка текста внутри блоков.

Пример добавления пользовательского inline-тега:

import MarkdownIt from "markdown-it";

const md = new MarkdownIt();

md.inline.ruler.push("highlight", (state, silent) => {
    const marker = "==";
    const start = state.pos;

    if (state.src.slice(start, start + 2) !== marker) return false;

    let end = state.src.indexOf(marker, start + 2);
    if (end === -1) return false;

    if (!silent) {
        const token = state.push("highlight_open", "mark", 1);
        token.content = state.src.slice(start + 2, end);
        state.push("highlight_close", "mark", -1);
    }

    state.pos = end + 2;
    return true;
});

Это правило преобразует ==выделенный текст== в HTML-тег <mark>.


Работа с типами и безопасность

TypeScript позволяет полностью типизировать работу с Markdown-it. Для примера, можно создать типизированную обёртку:

type MarkdownRenderer = {
    render: (text: string) => string;
    renderInline: (text: string) => string;
};

const createRenderer = (): MarkdownRenderer => {
    const md = new MarkdownIt({ html: true });
    return {
        render: (text) => md.render(text),
        renderInline: (text) => md.renderInline(text)
    };
};

const renderer = createRenderer();
const html = renderer.render("# Типизированный Markdown");

Типизация предотвращает ошибки при работе с плагинами и правилами, например, если плагин не поддерживает определённые опции.


Настройка рендеринга отдельных токенов

Markdown-it строит дерево токенов при разборе текста. Можно модифицировать токены перед генерацией HTML:

import MarkdownIt from "markdown-it";

const md = new MarkdownIt();

md.core.ruler.push("custom_uppercase", (state) => {
    state.tokens.forEach((token) => {
        if (token.type === "inline") {
            token.children?.forEach((child) => {
                if (child.type === "text") {
                    child.content = child.content.toUpperCase();
                }
            });
        }
    });
});

const text = "Пример текста для рендеринга.";
console.log(md.render(text)); // Весь текст будет в верхнем регистре

Этот подход позволяет создавать сложные трансформации Markdown перед финальным рендером.


Интеграция с современными фреймворками

Markdown-it легко интегрируется с React и Vue, благодаря своей независимости от DOM. Пример с React и TypeScript:

import React from "react";
import MarkdownIt from "markdown-it";

const md = new MarkdownIt();

type MarkdownProps = {
    content: string;
};

export const MarkdownRenderer: React.FC<MarkdownProps> = ({ content }) => {
    const html = md.render(content);
    return <div dangerouslySetInnerHTML={{ __html: html }} />;
};

Использование TypeScript обеспечивает проверку типов props и предотвращает ошибки при передаче содержимого Markdown.


Производительность и кеширование

Для больших объемов Markdown текста полезно использовать кеширование результата:

const cache = new Map<string, string>();

function renderMarkdown(text: string): string {
    if (cache.has(text)) {
        return cache.get(text)!;
    }
    const html = md.render(text);
    cache.set(text, html);
    return html;
}

Это уменьшает нагрузку при повторном рендеринге одинаковых фрагментов текста.


Вывод

Markdown-it в сочетании с TypeScript позволяет создавать полностью типизированные, расширяемые и производительные решения для обработки Markdown. Использование плагинов, кастомных правил и токенов открывает широкие возможности для точной настройки рендеринга и интеграции в фронтенд-приложения.