Работа с Markdown в C++: обзор библиотек и примеры использования
Markdown — это легковесный язык разметки, широко используемый для форматирования текста в документации, README-файлах, блогах и системах управления контентом. В экосистеме C++ существует несколько зрелых библиотек, которые позволяют парсить Markdown и конвертировать его в HTML или другие форматы. В этой статье мы рассмотрим три популярных инструмента: md4c, cmark и cpp-markdown, а также приведём практические примеры их использования.
1. Библиотека md4c
md4c — это легковесный парсер Markdown, написанный на чистом C (с C++-совместимыми заголовками). Он поддерживает спецификацию CommonMark и расширения GitHub Flavored Markdown (GFM), включая таблицы, зачёркивание и автоссылки. Библиотека отличается высокой производительностью и минимальным потреблением памяти.
Основные возможности:
- Соблюдение стандарта CommonMark 0.30.
- Поддержка расширений GFM (таблицы, task list, strikethrough).
- API для пошагового разбора (SAX-подобный) и генерация HTML.
- Отсутствие внешних зависимостей.
Пример использования md4c для конвертации Markdown в HTML:
#include <md4c-html.h>
#include <iostream>
#include <string>
// Callback для записи HTML-вывода
static void append_html(const MD_CHAR* text, MD_SIZE size, void* userdata) {
std::string* output = static_cast<std::string*>(userdata);
output->append(text, size);
}
int main() {
std::string markdown = "# Hello, **World**!\n\nThis is a *test*.";
std::string html;
MD_HTML_FLAGS flags = MD_HTML_FLAG_SKIP_UTF8_BOM;
int result = md_html(markdown.c_str(), markdown.length(),
append_html, &html, flags, 0);
if (result == 0) {
std::cout << html << std::endl;
} else {
std::cerr << "Parsing failed" << std::endl;
}
return 0;
}
2. Библиотека cmark
cmark (ранее cmark-gfm) — это эталонная реализация парсера CommonMark от сообщества. Она также написана на C и предоставляет C++-обёртку. Библиотека активно поддерживается, используется в таких проектах, как GitHub, GitLab и Pandoc.
Ключевые особенности:
- Полная поддержка CommonMark (включая последнюю версию спецификации).
- Встроенная поддержка GitHub Flavored Markdown (таблицы, формулы, упоминания).
- Генерация HTML, LaTeX, man, XML и других форматов.
- API для программного управления AST (Abstract Syntax Tree).
Пример использования cmark для парсинга и вывода HTML:
#include <cmark-gfm.h>
#include <iostream>
int main() {
const char* markdown = "## Список дел\n\n- [x] Купить молоко\n- [ ] Позвонить другу";
// Парсинг с поддержкой GFM
cmark_node* doc = cmark_parse_document(markdown, strlen(markdown), CMARK_OPT_DEFAULT);
// Конвертация в HTML
char* html = cmark_render_html(doc, CMARK_OPT_DEFAULT, NULL);
std::cout << html << std::endl;
// Освобождение памяти
free(html);
cmark_node_free(doc);
return 0;
}
3. Библиотека cpp-markdown
cpp-markdown — это C++-библиотека, написанная с нуля с использованием STL и современных возможностей C++11/14. Она ориентирована на простоту интеграции и удобство использования в C++-проектах. В отличие от md4c и cmark, она не требует внешних C-зависимостей.
Особенности:
- Реализация на чистом C++ (шаблоны, RAII, исключения).
- Поддержка базового синтаксиса Markdown (заголовки, списки, ссылки, изображения).
- Расширяемая архитектура (можно добавлять свои правила парсинга).
- Простая установка через CMake или header-only режим.
Пример использования cpp-markdown:
#include <markdown.hpp>
#include <iostream>
int main() {
std::string markdown = "## Пример кода\n\n```cpp\nstd::cout << \"Hello\";\n```";
// Пар