Работа с Markdown в C++: обзор библиотек и инструментов
Markdown — это легковесный язык разметки, широко используемый для форматирования текста в документации, README-файлах, блогах и образовательных проектах. В C++ нет встроенной поддержки Markdown, однако существует несколько зрелых и производительных библиотек, которые позволяют парсить Markdown и конвертировать его в HTML или другие форматы. В этой статье мы рассмотрим основные библиотеки для работы с Markdown в C++, их возможности, примеры использования и рекомендации по выбору.
Зачем нужна работа с Markdown в C++?
Применение Markdown в C++-проектах может быть разнообразным:
- Генерация статической документации из Markdown-файлов.
- Создание редакторов с предпросмотром разметки.
- Обработка пользовательского контента (комментарии, статьи) на серверной стороне.
- Интеграция с системами управления контентом (CMS) и образовательными платформами.
Выбор правильной библиотеки критически важен для производительности и безопасности, особенно если вы обрабатываете пользовательский ввод.
Основные библиотеки для работы с Markdown в C++
1. md4c
md4c — это компактная и быстрая библиотека для парсинга Markdown, написанная на C. Она поддерживает спецификацию CommonMark и часть расширений GFM (GitHub Flavored Markdown). Библиотека не генерирует HTML напрямую, а предоставляет SAX-подобный интерфейс событий, что даёт полный контроль над выводом.
Основные возможности:
- Поддержка CommonMark 0.30.
- Режимы: парсинг с генерацией дерева разбора (MD_PARSE_FLAG_COLLAPSEWHITESPACE) или без.
- Поддержка таблиц, списков задач, флагов для GFM.
- Минимальное потребление памяти.
Пример использования md4c для конвертации Markdown в HTML
#include <md4c.h>
#include <string>
#include <iostream>
// Функция обратного вызова для генерации HTML
static int render_html(const MD_CHAR* text, MD_SIZE size, void* userdata) {
std::string* html = static_cast<std::string*>(userdata);
html->append(text, size);
return 0;
}
int main() {
std::string markdown = "# Hello, **world**!\n\nЭто пример *Markdown*.";
std::string html;
MD_PARSER parser = {
0, // flags: можно добавить MD_FLAG_COLLAPSEWHITESPACE
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
render_html, // callback для текста
nullptr, nullptr
};
md_parse(markdown.c_str(), markdown.size(), &parser, &html);
std::cout << html << std::endl;
return 0;
}
Этот код демонстрирует минимальную интеграцию: библиотека вызывает render_html для каждого текстового фрагмента. Для полной реализации HTML-рендеринга потребуется обработка всех событий (заголовки, списки, ссылки и т.д.).
2. CMark
CMark — это библиотека на C, реализующая спецификацию CommonMark. Она является эталонной реализацией и используется в таких проектах, как GitHub и Stack Overflow. CMark предоставляет как парсер, так и рендереры для HTML, XML, LaTeX и man-страниц.
Основные возможности:
- Полная поддержка CommonMark 0.31.2.
- Расширения: таблицы, зачёркивание, автоссылки.
- Генерация AST (абстрактного синтаксического дерева) для кастомной обработки.
- Хорошая документация и активное сообщество.
Пример использования CMark
#include <cmark.h>
#include <iostream>
int main() {
const char* markdown = "## Заголовок\n\nТекст с *курсивом* и **жирным**.";
char* html = cmark_markdown_to_html(markdown, strlen(markdown), CMARK_OPT_DEFAULT);
if (html) {
std::cout << html << std::endl;
free(html);
}
return 0;
}
Этот код конвертирует Markdown в HTML одной функцией. CMark также позволяет работать с AST для более тонкой настройки вывода.
3. MD4C (расширенная версия)
Существует форк md4c с именем md4c-html, который добавляет встроенный HTML-рендерер. Это упрощает использование, так как