Syntax Highlighting Guide
July 16, 2025 ยท View on GitHub
SwiftMarkdownParser includes professional-grade syntax highlighting for code blocks with support for multiple programming languages, built-in themes, and extensible architecture.
๐ Features
- 6 Programming Languages: JavaScript, TypeScript, Swift, Kotlin, Python, Bash
- 3 Built-in Themes: GitHub, Xcode, VS Code Dark (HTML renderer only)
- 25+ Token Types: Keywords, strings, comments, operators, types, functions, and more
- Modern Language Features: ES6+, async/await, generics, coroutines, decorators
- Performance Optimized: Actor-based engine registry with LRU caching
- Thread-Safe: Built with Swift 6 concurrency patterns
- HTML Renderer: Full syntax highlighting with CSS classes and themes
- SwiftUI Renderer: Basic code blocks with monospace styling (no syntax highlighting)
๐ Quick Start
Basic HTML Rendering with Syntax Highlighting
import SwiftMarkdownParser
let codeMarkdown = """
# Code Example
```swift
@State private var count: Int = 0
func increment() async {
await MainActor.run {
count += 1
}
}
"""
// Configure syntax highlighting let context = RenderContext( styleConfiguration: StyleConfiguration( syntaxHighlighting: SyntaxHighlightingConfig( enabled: true, cssPrefix: "hljs-" // optional; default is "language-" ) ) )
let parser = SwiftMarkdownParser() let ast = try await parser.parseToAST(codeMarkdown)
let renderer = HTMLRenderer(context: context) let highlightedHTML = try await renderer.render(document: ast)
### SwiftUI Integration (Basic Code Blocks Only)
**Note**: SwiftUI renderer does NOT support syntax highlighting. It only renders plain monospace code blocks.
```swift
import SwiftUI
import SwiftMarkdownParser
struct CodeExampleView: View {
let markdown = """
```python
async def fetch_data():
response = await http.get('/api/data')
return await response.json()
```
"""
var body: some View {
ScrollView {
MarkdownView(markdown: markdown)
.padding()
}
}
}
struct MarkdownView: View {
let markdown: String
@State private var renderedView: AnyView?
var body: some View {
Group {
if let view = renderedView {
view
} else {
ProgressView("Rendering...")
}
}
.task {
await renderMarkdown()
}
}
private func renderMarkdown() async {
do {
let parser = SwiftMarkdownParser()
let ast = try await parser.parseToAST(markdown)
// Use a predefined SwiftUI style - NO syntax highlighting available
let context = SwiftUIRenderContext(
styleConfiguration: SwiftUIStyleConfiguration.github
)
let renderer = SwiftUIRenderer(context: context)
let view = try await renderer.render(document: ast)
await MainActor.run {
self.renderedView = view
}
} catch {
await MainActor.run {
self.renderedView = AnyView(Text("Error: \(error.localizedDescription)"))
}
}
}
}
๐ Supported Languages
JavaScript
- ES6+ Features: Arrow functions, destructuring, template literals
- Modern Syntax: async/await, classes, modules
- JSX Support: React component syntax
- Template Literals: String interpolation with
${}
const fetchUser = async (id) => {
const response = await fetch(`/api/users/${id}`);
return await response.json();
};
const UserComponent = ({ user }) => (
<div className="user-card">
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
TypeScript
- Type Annotations: Parameters, return types, variables
- Generics: Type parameters and constraints
- Interfaces: Object type definitions
- Decorators: Class and method decorators
- TSX Support: TypeScript + JSX
interface User {
id: number;
name: string;
email?: string;
}
@Component({
selector: 'user-list'
})
class UserList<T extends User> {
users: T[] = [];
async loadUsers(): Promise<void> {
this.users = await this.userService.getUsers<T>();
}
}
Swift
- Swift 6 Syntax: Latest language features
- Property Wrappers: @State, @Binding, @Published
- String Interpolation: (expression) syntax
- Async/Await: Modern concurrency
- Closures: Including shorthand syntax ($0, $1)
@State private var users: [User] = []
@Published var isLoading = false
func loadUsers() async throws {
let response = try await URLSession.shared.data(from: url)
users = try JSONDecoder().decode([User].self, from: response.0)
}
let sorted = users.sorted { \$0.name < \$1.name }
Kotlin
- Data Classes: Automatic implementations
- Coroutines: suspend functions, async/await
- Null Safety: ? and ?: operators
- Extension Functions: Adding methods to existing types
data class User(val name: String, var age: Int)
suspend fun fetchUser(id: String): User? = withContext(Dispatchers.IO) {
val response = httpClient.get("/api/users/$id")
response.body<User>()
}
fun String.isEmail(): Boolean = this.contains('@')
Python
- Python 3+ Syntax: Modern Python features
- Async/Await: Asynchronous programming
- Triple-quoted Strings: Multi-line strings
- List Comprehensions: Functional programming constructs
- Type Hints: Optional type annotations
from typing import List, Optional
async def fetch_users() -> List[User]:
async with aiohttp.ClientSession() as session:
async with session.get('/api/users') as response:
return await response.json()
users = [user for user in all_users if user.age >= 18]
Bash
- Shell Scripts: Complete bash syntax
- Variables: {VAR} syntax
- Control Structures: if/then/fi, for/do/done
- Built-in Commands: Common shell utilities
- Shebang: #!/bin/bash detection
#!/bin/bash
USER_COUNT=$(wc -l < users.txt)
if [ $USER_COUNT -gt 100 ]; then
echo "Many users: $USER_COUNT"
for user in $(cat users.txt); do
echo "Processing: $user"
done
fi
๐จ Built-in Themes
Important: Themes are only available for the HTML renderer. The SwiftUI renderer uses basic monospace styling without syntax highlighting.
GitHub Theme
Clean, professional styling matching GitHub's code blocks:
- Background: Light gray (#f6f8fa)
- Keywords: Deep red (#d73a49)
- Strings: Dark blue (#032f62)
- Comments: Gray (#6a737d)
Xcode Theme
Apple's development environment colors:
- Background: White
- Keywords: Purple (#aa0d91)
- Strings: Red (#c41a16)
- Comments: Green (#008400)
VS Code Dark Theme
Popular dark theme for developers:
- Background: Dark gray (#1e1e1e)
- Keywords: Light blue (#4fc3f7)
- Strings: Orange (#ce9178)
- Comments: Green (#6a9955)
๐ ๏ธ Configuration
HTML Renderer Configuration
let syntaxConfig = SyntaxHighlightingConfig(
enabled: true,
cssPrefix: "hljs-" // optional; default is "language-"
)
let context = RenderContext(
styleConfiguration: StyleConfiguration(
syntaxHighlighting: syntaxConfig
)
)
SwiftUI Renderer Configuration
Note: SwiftUI renderer does not support syntax highlighting. Only basic styling is available.
let context = SwiftUIRenderContext(
styleConfiguration: SwiftUIStyleConfiguration(
// Only basic code styling - no syntax highlighting
codeFont: .system(.body, design: .monospaced),
codeTextColor: .primary,
codeBackgroundColor: Color.gray.opacity(0.1),
codeCornerRadius: 8.0
)
)
๐จ Custom Themes
Creating Custom Themes (HTML Renderer Only)
// Custom CSS classes for HTML output
let context = RenderContext(
styleConfiguration: StyleConfiguration(
syntaxHighlighting: SyntaxHighlightingConfig(
enabled: true,
cssPrefix: "custom-"
),
cssClasses: [
.codeBlock: "my-code-block"
]
)
)
// Then provide your own CSS rules:
// .custom-keyword { color: #0066cc; }
// .custom-string { color: #009900; }
// .custom-comment { color: #888888; }
SwiftUI Basic Styling
// Only basic styling available for SwiftUI
let customStyle = SwiftUIStyleConfiguration(
codeFont: .system(.footnote, design: .monospaced),
codeTextColor: Color.blue,
codeBackgroundColor: Color.gray.opacity(0.05),
codeCornerRadius: 4.0
)
let context = SwiftUIRenderContext(styleConfiguration: customStyle)
Theme Color Mapping
The syntax highlighting system supports 25+ token types:
| Token Type | Description | Example |
|---|---|---|
.keyword | Language keywords | func, class, if, async |
.string | String literals | "Hello", 'world' |
.comment | Comments | // comment, /* block */ |
.number | Numeric literals | 42, 3.14, 0xFF |
.identifier | Variable names | userName, count |
.operator | Operators | +, -, ==, && |
.punctuation | Punctuation | (, ), {, }, ; |
.type | Type names | String, Int, User |
.function | Function names | print, map, filter |
.builtin | Built-in functions | console.log, len, echo |
.constant | Constants | true, false, null |
.attribute | Attributes/decorators | @State, @Component |
.generic | Generic parameters | <T>, <K, V> |
.method | Method calls | user.getName() |
.property | Object properties | user.name |
.parameter | Function parameters | $0, $1 |
.modifier | Access modifiers | public, private |
.template | Template literals | `Hello ${name}` |
.interpolation | String interpolation | ${name}, \(value) |
.regex | Regular expressions | /pattern/flags |
.escape | Escape sequences | \n, \t, \" |
โก Performance
Caching System
The syntax highlighting system includes an intelligent caching mechanism:
// Access the registry for performance monitoring
let registry = SyntaxHighlightingRegistry()
// Get cache statistics
let cache = SyntaxHighlightingCache()
let stats = await cache.getStatistics()
print("Cache entries: \(stats["entryCount"] ?? 0)")
print("Total hits: \(stats["totalHits"] ?? 0)")
// Clear cache if needed
await cache.clearCache()
Performance Features
- LRU Cache: Least Recently Used eviction policy
- Actor-based: Thread-safe concurrent access
- Lazy Loading: Engines loaded only when needed
- Efficient Parsing: Single-pass tokenization
- Memory Efficient: Minimal allocations during highlighting
Benchmarks
Performance characteristics for different code block sizes (HTML renderer):
| Lines of Code | Highlighting Time | Memory Usage |
|---|---|---|
| 10-50 lines | < 1ms | < 10KB |
| 100-500 lines | < 5ms | < 50KB |
| 1000+ lines | < 20ms | < 200KB |
Note: SwiftUI renderer performance is simpler as it doesn't perform syntax highlighting.
๐ง Advanced Usage
Direct Engine Access
// Use engines directly for custom processing
let jsEngine = JavaScriptSyntaxEngine()
let tokens = try await jsEngine.highlight(
"const x = 42;",
language: "javascript"
)
// Process tokens for HTML output
for token in tokens {
print("\(token.content): \(token.tokenType)")
}
Custom Engine Registration
// Register a custom engine
struct MyLanguageEngine: SyntaxHighlightingEngine {
func highlight(_ code: String, language: String) async throws -> [SyntaxToken] {
// Custom highlighting logic
return []
}
func supportedLanguages() -> Set<String> {
return ["mylang"]
}
}
let registry = SyntaxHighlightingRegistry()
await registry.register(engine: MyLanguageEngine(), for: ["mylang"])
Error Handling
do {
let tokens = try await engine.highlight(code, language: "swift")
// Process tokens
} catch SyntaxHighlightingError.unsupportedLanguage(let lang) {
print("Language not supported: \(lang)")
} catch SyntaxHighlightingError.parsingError(let message) {
print("Parsing error: \(message)")
} catch {
print("Unknown error: \(error)")
}
๐งช Testing
Unit Tests
The syntax highlighting system includes comprehensive tests:
# Run all syntax highlighting tests
swift test --filter SyntaxHighlightingEngineTests
# Run specific language tests
swift test --filter test_swiftEngine
swift test --filter test_javascriptEngine
# Run integration tests (HTML renderer)
swift test --filter SyntaxHighlightingIntegrationTests
Test Coverage
- Engine Tests: Each language engine has dedicated tests
- Theme Tests: Color theme functionality (HTML only)
- Registry Tests: Engine registration and caching
- Performance Tests: Large code block handling
- Edge Cases: Malformed code, empty blocks, special characters
๐ Examples
Complete HTML Example with Syntax Highlighting
import SwiftMarkdownParser
let multiLanguageMarkdown = """
# Multi-language Code Examples
## Frontend (TypeScript + React)
```typescript
interface User {
id: number;
name: string;
email: string;
}
const UserCard: React.FC<{ user: User }> = ({ user }) => (
<div className="user-card">
<h3>{user.name}</h3>
<p>{user.email}</p>
</div>
);
Backend (Swift)
struct User: Codable {
let id: Int
let name: String
let email: String
}
@main
struct App {
static func main() async throws {
let users = try await UserService.fetchUsers()
print("Loaded \(users.count) users")
}
}
"""
async func generateHighlightedHTML() throws -> String { let parser = SwiftMarkdownParser() let ast = try await parser.parseToAST(multiLanguageMarkdown)
let context = RenderContext(
styleConfiguration: StyleConfiguration(
syntaxHighlighting: SyntaxHighlightingConfig(
enabled: true,
cssPrefix: "hljs-"
),
cssClasses: [
.codeBlock: "code-block highlighted",
.heading: "section-heading"
]
)
)
let renderer = HTMLRenderer(context: context)
return try await renderer.render(document: ast)
}
// Usage let html = try await generateHighlightedHTML() print(html)
### SwiftUI Example (Basic Code Blocks)
```swift
import SwiftUI
import SwiftMarkdownParser
struct SwiftUICodeExample: View {
let codeMarkdown = """
```swift
let message = "Hello, World!"
print(message)
```
"""
@State private var renderedView: AnyView?
var body: some View {
VStack {
if let view = renderedView {
view
} else {
ProgressView("Rendering...")
}
}
.task {
await renderCode()
}
}
private func renderCode() async {
do {
let parser = SwiftMarkdownParser()
let ast = try await parser.parseToAST(codeMarkdown)
// SwiftUI basic styling - no syntax highlighting
let context = SwiftUIRenderContext(
styleConfiguration: SwiftUIStyleConfiguration(
codeFont: .system(.body, design: .monospaced),
codeTextColor: .primary,
codeBackgroundColor: Color.gray.opacity(0.1)
)
)
let renderer = SwiftUIRenderer(context: context)
let view = try await renderer.render(document: ast)
await MainActor.run {
self.renderedView = view
}
} catch {
await MainActor.run {
self.renderedView = AnyView(Text("Error: \(error.localizedDescription)"))
}
}
}
}
๐ Renderer Comparison
| Feature | HTML Renderer | SwiftUI Renderer |
|---|---|---|
| Syntax Highlighting | โ Full support | โ Not supported |
| Themes | โ 3 built-in themes | โ Basic styling only |
| Token-level styling | โ 25+ token types | โ Plain text only |
| Custom CSS classes | โ Configurable | โ N/A |
| Performance | โ Cached highlighting | โ Simple rendering |
| Use case | Web/HTML output | Native iOS/macOS apps |
The syntax highlighting system in SwiftMarkdownParser provides professional-grade code block rendering for HTML output with modern language support, beautiful themes, and excellent performance. For SwiftUI applications, basic monospace code blocks are provided without syntax highlighting. ๐จโจ