Работа с Markdown в C++: библиотеки md4c, cmark и cpp-markdown

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с 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```";
    
    // Пар                    

Рекомендаций