splash/Sources/Splash/Output/AttributedStringOutputFormat.swift
John Sundell 1e532a6c4c Theme: Streamline cross-platform implementation
Now that we’re making Splash support iOS as well as
Mac + Linux, we need to create some nice abstractions
to make sure that we can share as much code as possible
between all platforms.

- Define Font.Loaded and Color.Renderable as platform-
specific typealiases for system fonts and colors.
- Don’t compile in non-Linux compatible code when building
for Linux.
- Make Font and Color handle all conversion themselves, so
that AttributedStringOutputFormat can be kept more clean.
2018-08-26 00:54:44 +02:00

68 lines
1.9 KiB
Swift

/**
* Splash
* Copyright (c) John Sundell 2018
* MIT license - see LICENSE.md
*/
#if !os(Linux)
import Foundation
/// Output format to use to generate an NSAttributedString from the
/// highlighted code. A `Theme` is used to determine what fonts and
/// colors to use for the various tokens.
public struct AttributedStringOutputFormat: OutputFormat {
public var theme: Theme
public init(theme: Theme) {
self.theme = theme
}
public func makeBuilder() -> Builder {
return Builder(theme: theme)
}
}
public extension AttributedStringOutputFormat {
struct Builder: OutputBuilder {
private let theme: Theme
private lazy var font = theme.font.load()
private var string = NSMutableAttributedString()
fileprivate init(theme: Theme) {
self.theme = theme
}
public mutating func addToken(_ token: String, ofType type: TokenType) {
let color = theme.tokenColors[type] ?? Color(red: 1, green: 1, blue: 1)
string.append(token, font: font, color: color)
}
public mutating func addPlainText(_ text: String) {
string.append(text, font: font, color: theme.plainTextColor)
}
public mutating func addWhitespace(_ whitespace: String) {
let color = Color(red: 1, green: 1, blue: 1)
string.append(whitespace, font: font, color: color)
}
public func build() -> NSAttributedString {
return NSAttributedString(attributedString: string)
}
}
}
private extension NSMutableAttributedString {
func append(_ string: String, font: Font.Loaded, color: Color) {
let attributedString = NSAttributedString(string: string, attributes: [
.foregroundColor: color.renderable,
.font: font
])
append(attributedString)
}
}
#endif