Обработка Markdown в Swift для iOS и macOS: библиотеки и примеры

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

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

Начать курс

Работа с Markdown в Swift (iOS/macOS): библиотеки и практические примеры

Markdown — это легковесный язык разметки, широко используемый для форматирования текста в документации, чатах и образовательных приложениях. В экосистеме Swift (iOS/macOS) существует несколько зрелых библиотек, которые позволяют парсить, рендерить и конвертировать Markdown в нативные представления. В этой статье мы рассмотрим основные инструменты: Down, Ink и SwiftMarkdown, а также покажем примеры интеграции в SwiftUI и UIKit.

1. Библиотека Down (cmark-based)

Down — самая популярная библиотека для работы с Markdown в Swift. Она основана на высокопроизводительном C-парсере cmark и поддерживает стандарт CommonMark. Down позволяет конвертировать Markdown в HTML, NSAttributedString, PDF и даже в AST (абстрактное синтаксическое дерево).

Установка

Добавьте в Package.swift:

dependencies: [
    .package(url: "https://github.com/johnxnguyen/Down.git", from: "0.9.4")
]

Пример: рендеринг Markdown в NSAttributedString

import Down

let markdownString = "# Заголовок\n\nЭто **жирный** текст и *курсив*."
let down = Down(markdownString: markdownString)

do {
    let attributedString = try down.toAttributedString()
    // Используйте в UITextView или UILabel
    textView.attributedText = attributedString
} catch {
    print("Ошибка парсинга: \(error)")
}

Down также поддерживает кастомные стили через DownStyler:

let styler = DownStyler(configuration: DownStylerConfiguration(
    fonts: FontCollection(
        heading1: .boldSystemFont(ofSize: 24),
        body: .systemFont(ofSize: 16)
    ),
    colors: ColorCollection(
        heading1: .systemBlue,
        body: .label
    )
))
let attributedString = try down.toAttributedString(styler: styler)

2. Библиотека Ink (John Sundell)

Ink — легковесный парсер Markdown от автора John Sundell. Он не требует внешних зависимостей (чистый Swift) и идеально подходит для простых задач: извлечения заголовков, списков, ссылок. Ink возвращает дерево блоков (block-level elements), которое можно кастомизировать.

Установка через Swift Package Manager

dependencies: [
    .package(url: "https://github.com/JohnSundell/Ink.git", from: "0.6.0")
]

Пример: парсинг и извлечение заголовков

import Ink

let markdown = """
# Главный заголовок
## Подзаголовок
Обычный текст с **жирным** выделением.
"""

let parser = MarkdownParser()
let result = parser.parse(markdown)

for heading in result.headings {
    print("Уровень \(heading.level): \(heading.text)")
}
// Вывод:
// Уровень 1: Главный заголовок
// Уровень 2: Подзаголовок

Ink также поддерживает кастомные модификаторы для расширения синтаксиса:

let modifier = Modifier(target: .inlineCode) { html, markdown in
    return "<span style=\"color: red;\">\(html)</span>"
}
let parser = MarkdownParser(modifiers: [modifier])

3. SwiftMarkdown (от Apple)

SwiftMarkdown — официальная библиотека от Apple, представленная на WWDC 2022. Она глубоко интегрирована с экосистемой SwiftUI и поддерживает все расширения Markdown, включая таблицы, блоки кода с подсветкой и вложенные списки. SwiftMarkdown использует AttributedString из Foundation, что упрощает локализацию и динамические шрифты.

Установка

Добавьте в проект через Xcode: File → Add Packages → apple/swift-markdown.

Пример: отображение Markdown в SwiftUI

import MarkdownUI
import SwiftUI

struct ContentView: View {
    let markdown = """
    # Добро пожаловать
    Это **пример** использования SwiftMarkdown.
    - Пункт 1
    - Пункт 2

    Код: `let x = 10`
    """

    var body: some View {
        ScrollView {
            Markdown(markdown)
                .markdownStyle(.init(
                    font: .body,
                    heading1: .title,
                    code: .monospaced
                ))
                .padding()
        }
    }
}

SwiftMarkdown также позволяет рендерить Markdown в NSAttributedString для UIKit:

import Markdown

let source = "# Привет, мир!"
let document = Document(parsing: source)
let attributedString = AttributedString(document)
// Используйте в UITextView                    

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