Обработка Markdown в Swift для iOS и macOS: от парсинга до рендеринга
Markdown — один из самых популярных языков разметки для форматирования текста. В экосистеме Swift (iOS/macOS) существует несколько мощных библиотек, которые позволяют парсить, конвертировать и отображать Markdown. В этой статье мы рассмотрим две основные библиотеки: Down (быстрый и гибкий) и SwiftMarkdown (официальная библиотека от Apple). Вы узнаете, как интегрировать их в свои проекты, преобразовывать Markdown в NSAttributedString, HTML и отображать в SwiftUI.
1. Библиотека Down (cmark-based)
Down — это обёртка над популярным C-парсером cmark, написанная на Swift. Она обеспечивает высокую производительность и поддерживает все основные элементы Markdown (заголовки, списки, код, ссылки, изображения, таблицы и т.д.).
Установка
Добавьте пакет через Swift Package Manager:
// Package.swift
dependencies: [
.package(url: "https://github.com/johnxnguyen/Down.git", from: "0.11.0")
]
Пример: конвертация Markdown в HTML
import Down
let markdownString = "# Привет, мир!\n\nЭто **жирный текст** и *курсив*."
let down = Down(markdownString: markdownString)
let html = try? down.toHTML()
print(html ?? "")
// Вывод: <h1>Привет, мир!</h1>\n<p>Это <strong>жирный текст</strong> и <em>курсив</em>.</p>
Рендеринг в NSAttributedString
Down умеет напрямую создавать NSAttributedString для отображения в UILabel, UITextView или NSTextView:
let attributedString = try? down.toAttributedString()
// Используйте в UITextView:
textView.attributedText = attributedString
Поддержка SwiftUI
Для SwiftUI можно создать обёртку, отображающую AttributedString (iOS 15+):
struct MarkdownView: View {
let markdown: String
var body: some View {
if let nsAttr = try? Down(markdownString: markdown).toAttributedString() {
Text(AttributedString(nsAttr))
} else {
Text(markdown)
}
}
}
2. SwiftMarkdown (от Apple)
SwiftMarkdown — это официальная библиотека Apple, входящая в swift-markdown. Она предоставляет полный парсер Markdown с возможностью кастомизации и генерации различных форматов (HTML, CommonMark, AST).
Установка
// Package.swift
dependencies: [
.package(url: "https://github.com/apple/swift-markdown.git", branch: "main")
]
Парсинг и работа с AST
Библиотека строит абстрактное синтаксическое дерево (AST), которое можно анализировать и модифицировать:
import Markdown
let source = """
# Документация
Список функций:
- `foo()` — первая функция
- `bar()` — вторая функция
"""
let document = Document(parsing: source)
let heading = document.child(at: 0) as? Heading
print(heading?.plainText ?? "") // "Документация"
// Обход всех элементов
for child in document.children {
if let list = child as? UnorderedList {
for item in list.children {
print((item as? ListItem)?.plainText ?? "")
}
}
}
Генерация HTML
let html = document.format(options: [.unsafeTags])
print(html)
// Вывод: <h1>Документация</h1>...<ul><li><code>foo()</code> — первая функция</li>...
Рендеринг через AttributedString (iOS 15+)
SwiftMarkdown поддерживает прямое преобразование в AttributedString с использованием стилей:
import Markdown
import SwiftUI
struct ContentView: View {
let markdown = "**Важно**: нажмите *здесь*."
var body: some View {
if let attributed = try? AttributedString(markdown: markdown) {
Text(attributed)
}
}
}
3. Сравнение Down vs SwiftMarkdown
- Производительность: Down быстрее за счёт C-ядра cmark. SwiftMarkdown медленнее, но полностью на Swift.
- Гибкость
Также в библиотеке
Рекомендаций