Работа с 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