Overview
MarkdownTheme provides comprehensive control over the visual appearance of rendered markdown, including fonts, colors, spacing, and component-specific styling. All theme properties use UIKit/AppKit native types for seamless integration.
Basic Theme Customization
Start with the default theme and customize specific properties:
var theme = MarkdownTheme ()
// Customize fonts
theme. fonts . body = . preferredFont ( forTextStyle : . body )
theme. fonts . code = . monospacedSystemFont ( ofSize : 14 , weight : . regular )
// Customize colors
theme. colors . body = . label
theme. colors . code = . secondaryLabel
theme. colors . codeBackground = . secondarySystemBackground
// Scale all fonts
theme. scaleFont ( by : . large )
markdownView. theme = theme
Theme Structure
MarkdownTheme is organized into five main categories:
Fonts Control typography for body text, code, headings, and emphasis
Colors Define colors for text, code, highlights, and selections
Spacings Adjust padding and margins between elements
Sizes Configure UI element dimensions like bullets
Component Styles Customize tables, images, and other components
Fonts Configuration
Available Font Properties
public struct Fonts {
public var body: UIFont // Main text font
public var codeInline: UIFont // Inline code (`code`)
public var bold: UIFont // Bold text
public var italic: UIFont // Italic text
public var code: UIFont // Code blocks
public var largeTitle: UIFont // H1 headings
public var title: UIFont // H2-H6 headings
public var footnote: UIFont // Small text
}
Custom Font Example
var theme = MarkdownTheme ()
// Use custom fonts
theme. fonts . body = UIFont ( name : "Georgia" , size : 17 ) !
theme. fonts . bold = UIFont ( name : "Georgia-Bold" , size : 17 ) !
theme. fonts . italic = UIFont ( name : "Georgia-Italic" , size : 17 ) !
// Use SF Mono for code
if let sfMono = UIFont ( name : "SFMono-Regular" , size : 14 ) {
theme. fonts . code = sfMono
theme. fonts . codeInline = sfMono
}
// Larger headings
theme. fonts . largeTitle = UIFont. systemFont ( ofSize : 32 , weight : . bold )
theme. fonts . title = UIFont. systemFont ( ofSize : 24 , weight : . bold )
Font Scaling
Use built-in scaling to adjust all fonts proportionally:
var theme = MarkdownTheme ()
// Scale by preset size
theme. scaleFont ( by : . tiny ) // -4 points
theme. scaleFont ( by : . small ) // -2 points
theme. scaleFont ( by : . middle ) // 0 points (default)
theme. scaleFont ( by : . large ) // +2 points
theme. scaleFont ( by : . huge ) // +4 points
Align to Specific Point Size
Set all fonts to scale from a base point size:
var theme = MarkdownTheme ()
// All fonts scale from 16pt base
theme. align ( to : 16 )
// Code blocks automatically scale to 85% of base
// code font will be ~13.6pt
The codeScale constant is set to 0.85, meaning code fonts are always 85% the size of body text for better readability.
Colors Configuration
Available Color Properties
public struct Colors {
public var body: UIColor // Main text color
public var highlight: UIColor // Links and highlighted text
public var emphasis: UIColor // Emphasized text
public var code: UIColor // Code text color
public var codeBackground: UIColor // Code block background
public var selectionBackground: UIColor ? // Text selection color
}
Dark Mode Support
Colors automatically adapt to light and dark mode when using dynamic colors:
var theme = MarkdownTheme ()
// Semantic colors adapt automatically
theme. colors . body = . label
theme. colors . code = . secondaryLabel
theme. colors . codeBackground = . secondarySystemBackground
// Custom dynamic colors
theme. colors . highlight = UIColor { traitCollection in
traitCollection. userInterfaceStyle == . dark
? UIColor ( red : 0.4 , green : 0.7 , blue : 1.0 , alpha : 1.0 )
: UIColor ( red : 0.0 , green : 0.5 , blue : 1.0 , alpha : 1.0 )
}
Custom Color Schemes
Nord Theme
Solarized Dark
Dracula
var theme = MarkdownTheme ()
// Nord color palette
theme. colors . body = UIColor ( red : 0.216 , green : 0.255 , blue : 0.318 , alpha : 1.0 )
theme. colors . code = UIColor ( red : 0.141 , green : 0.165 , blue : 0.208 , alpha : 1.0 )
theme. colors . codeBackground = UIColor ( red : 0.925 , green : 0.937 , blue : 0.957 , alpha : 1.0 )
theme. colors . highlight = UIColor ( red : 0.357 , green : 0.608 , blue : 0.835 , alpha : 1.0 )
theme. colors . emphasis = UIColor ( red : 0.741 , green : 0.380 , blue : 0.416 , alpha : 1.0 )
var theme = MarkdownTheme ()
// Solarized Dark
theme. colors . body = UIColor ( red : 0.514 , green : 0.580 , blue : 0.588 , alpha : 1.0 )
theme. colors . code = UIColor ( red : 0.396 , green : 0.482 , blue : 0.514 , alpha : 1.0 )
theme. colors . codeBackground = UIColor ( red : 0.027 , green : 0.212 , blue : 0.259 , alpha : 1.0 )
theme. colors . highlight = UIColor ( red : 0.149 , green : 0.545 , blue : 0.824 , alpha : 1.0 )
theme. colors . emphasis = UIColor ( red : 0.863 , green : 0.196 , blue : 0.184 , alpha : 1.0 )
var theme = MarkdownTheme ()
// Dracula theme
theme. colors . body = UIColor ( red : 0.945 , green : 0.945 , blue : 0.945 , alpha : 1.0 )
theme. colors . code = UIColor ( red : 0.847 , green : 0.855 , blue : 0.863 , alpha : 1.0 )
theme. colors . codeBackground = UIColor ( red : 0.173 , green : 0.173 , blue : 0.188 , alpha : 1.0 )
theme. colors . highlight = UIColor ( red : 0.486 , green : 0.506 , blue : 0.859 , alpha : 1.0 )
theme. colors . emphasis = UIColor ( red : 1.0 , green : 0.333 , blue : 0.494 , alpha : 1.0 )
Spacing Configuration
Available Spacing Properties
public struct Spacings {
public var final: CGFloat = 16 // Bottom margin of last element
public var general: CGFloat = 8 // General spacing between blocks
public var list: CGFloat = 8 // Spacing between list items
public var cell: CGFloat = 32 // Width of list item indent
}
Compact vs Spacious Layouts
// Compact layout
var compactTheme = MarkdownTheme ()
compactTheme. spacings . general = 4
compactTheme. spacings . list = 4
compactTheme. spacings . final = 8
// Spacious layout
var spaciousTheme = MarkdownTheme ()
spaciousTheme. spacings . general = 16
spaciousTheme. spacings . list = 12
spaciousTheme. spacings . final = 24
spaciousTheme. spacings . cell = 40
Size Configuration
Available Size Properties
public struct Sizes {
public var bullet: CGFloat = 4 // Bullet point diameter
}
Customizing Bullet Size
var theme = MarkdownTheme ()
// Larger bullets for readability
theme. sizes . bullet = 6
// Smaller, subtle bullets
theme. sizes . bullet = 3
Table Styling
Available Table Properties
public struct Table {
public var cornerRadius: CGFloat = 8
public var borderWidth: CGFloat = 1
public var borderColor: UIColor = . separator
public var headerBackgroundColor: UIColor = . systemGray6
public var cellBackgroundColor: UIColor = . clear
public var stripeCellBackgroundColor: UIColor = . systemGray . withAlphaComponent ( 0.03 )
}
Custom Table Styling
var theme = MarkdownTheme ()
// Modern rounded tables
theme. table . cornerRadius = 12
theme. table . borderWidth = 2
theme. table . borderColor = . systemBlue
theme. table . headerBackgroundColor = . systemBlue . withAlphaComponent ( 0.1 )
theme. table . stripeCellBackgroundColor = . systemGray . withAlphaComponent ( 0.05 )
// Borderless tables
theme. table . borderWidth = 0
theme. table . cornerRadius = 0
theme. table . cellBackgroundColor = . clear
Image Styling
Available Image Properties
public struct Image {
public var cornerRadius: CGFloat = 4
public var maxWidthFraction: CGFloat = 1.0
public var placeholderColor: UIColor = . systemGray5
}
Custom Image Styling
var theme = MarkdownTheme ()
// Rounded corners
theme. image . cornerRadius = 12
// Limit image width to 80% of container
theme. image . maxWidthFraction = 0.8
// Custom placeholder color
theme. image . placeholderColor = . systemGray4
Complete Theme Examples
Reader Mode Theme
func createReaderTheme () -> MarkdownTheme {
var theme = MarkdownTheme ()
// Comfortable reading fonts
theme. fonts . body = UIFont ( name : "Georgia" , size : 18 ) ?? . systemFont ( ofSize : 18 )
theme. fonts . bold = theme. fonts . body . bold
theme. fonts . italic = theme. fonts . body . italic
theme. fonts . largeTitle = UIFont ( name : "Georgia-Bold" , size : 36 ) ?? . boldSystemFont ( ofSize : 36 )
theme. fonts . title = UIFont ( name : "Georgia-Bold" , size : 28 ) ?? . boldSystemFont ( ofSize : 28 )
// Sepia colors
theme. colors . body = UIColor ( red : 0.2 , green : 0.18 , blue : 0.15 , alpha : 1.0 )
theme. colors . highlight = UIColor ( red : 0.65 , green : 0.45 , blue : 0.2 , alpha : 1.0 )
theme. colors . codeBackground = UIColor ( red : 0.96 , green : 0.95 , blue : 0.92 , alpha : 1.0 )
// Generous spacing
theme. spacings . general = 16
theme. spacings . list = 12
theme. spacings . final = 32
return theme
}
Code Documentation Theme
func createCodeDocsTheme () -> MarkdownTheme {
var theme = MarkdownTheme ()
// Technical fonts
theme. fonts . body = . systemFont ( ofSize : 15 )
theme. fonts . code = . monospacedSystemFont ( ofSize : 13 , weight : . medium )
theme. fonts . codeInline = . monospacedSystemFont ( ofSize : 14 , weight : . regular )
// Developer-friendly colors
theme. colors . codeBackground = UIColor ( red : 0.95 , green : 0.97 , blue : 0.98 , alpha : 1.0 )
theme. colors . code = UIColor ( red : 0.2 , green : 0.3 , blue : 0.4 , alpha : 1.0 )
theme. colors . highlight = . systemBlue
// Compact spacing for dense content
theme. spacings . general = 6
theme. spacings . list = 6
return theme
}
Accessing Default Values
You can access default values for each theme category:
let defaultFonts = MarkdownTheme. defaultValueFont
let defaultColors = MarkdownTheme. defaultValueColor
let defaultSpacings = MarkdownTheme. defaultValueSpacing
let defaultSizes = MarkdownTheme. defaultValueSize
let defaultTable = MarkdownTheme. defaultValueTable
// Use default as starting point
var theme = MarkdownTheme ()
theme. fonts = defaultFonts
theme. fonts . body = . preferredFont ( forTextStyle : . body )
Dynamic Type Support
Use Dynamic Type for accessibility:
var theme = MarkdownTheme ()
// Preferred fonts respect user's text size settings
theme. fonts . body = . preferredFont ( forTextStyle : . body )
theme. fonts . title = . preferredFont ( forTextStyle : . title1 )
theme. fonts . largeTitle = . preferredFont ( forTextStyle : . largeTitle )
theme. fonts . footnote = . preferredFont ( forTextStyle : . footnote )
// Code can use preferred monospace
if #available ( iOS 13.0 , * ) {
theme. fonts . code = . monospacedSystemFont (
ofSize : UIFont. preferredFont ( forTextStyle : . body ). pointSize * 0.85 ,
weight : . regular
)
}
When using Dynamic Type, remember to observe UIContentSizeCategory changes and update your theme accordingly for the best accessibility experience.
Platform Differences
MarkdownTheme uses #if canImport(UIKit) and #elseif canImport(AppKit) for cross-platform compatibility:
iOS/visionOS : Uses UIFont and UIColor
macOS : Uses NSFont and NSColor
The API remains identical across platforms, just use the appropriate platform types:
# if canImport ( UIKit )
import UIKit
var theme = MarkdownTheme ()
theme. colors . body = UIColor. label
# elseif canImport ( AppKit )
import AppKit
var theme = MarkdownTheme ()
theme. colors . body = NSColor. labelColor
# endif