diff --git a/Sources/Splash/Output/AttributedStringOutputFormat.swift b/Sources/Splash/Output/AttributedStringOutputFormat.swift index 4a54733..603eb80 100644 --- a/Sources/Splash/Output/AttributedStringOutputFormat.swift +++ b/Sources/Splash/Output/AttributedStringOutputFormat.swift @@ -5,6 +5,7 @@ */ #if !os(Linux) +#if canImport(SwiftUI) import Foundation @@ -65,3 +66,4 @@ private extension NSMutableAttributedString { } #endif +#endif diff --git a/Sources/Splash/Output/SwiftUITextOutputFormat.swift b/Sources/Splash/Output/SwiftUITextOutputFormat.swift new file mode 100644 index 0000000..ac8844f --- /dev/null +++ b/Sources/Splash/Output/SwiftUITextOutputFormat.swift @@ -0,0 +1,81 @@ +// +// SwiftUITextOutputFormat.swift +// +// Created by Andrew Eades on 02/01/2020. +// Copyright © 2020 Andrew Eades. All rights reserved. +// + + +#if !os(Linux) +#if canImport(SwiftUI) + +import SwiftUI + +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 SwiftUITextOutputFormat: OutputFormat { + public var theme: Theme + + public init(theme: Theme) { + self.theme = theme + } + + public func makeBuilder() -> Builder { + return Builder(theme: theme) + } +} + +public extension SwiftUITextOutputFormat { + struct Builder: OutputBuilder { + private let theme: Theme + private var texts = [Text]() + + fileprivate init(theme: Theme) { + self.theme = theme + } + + public mutating func addToken(_ token: String, ofType type: TokenType) { + let tokenColor = swiftUIColor(forType: type) + + texts.append(Text(token).foregroundColor(tokenColor)) + } + + public mutating func addPlainText(_ plainText: String) { + let tokenColor = SwiftUI.Color(theme.plainTextColor) + + texts.append(Text(plainText).foregroundColor(tokenColor)) + } + + public mutating func addWhitespace(_ whitespace: String) { + let tokenColor = SwiftUI.Color.white + + texts.append(Text(whitespace).foregroundColor(tokenColor)) + } + + public func build() -> Text { + + let highlightedText = texts.reduce(Text(""), +) + + return highlightedText + } + + private func swiftUIColor(forType type: TokenType) -> SwiftUI.Color { + var tokenColor: SwiftUI.Color + + if let color = theme.tokenColors[type] { + tokenColor = SwiftUI.Color(color) + } else { + tokenColor = SwiftUI.Color.white + } + + return tokenColor + } + + } +} + +#endif +#endif