Implements iOS support for AttributedStringOutputFormat
This commit is contained in:
parent
54598263bb
commit
5702cea843
@ -5,19 +5,23 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
|
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
import UIKit
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Output format to use to generate an NSAttributedString from the
|
/// Output format to use to generate an NSAttributedString from the
|
||||||
/// highlighted code. A `Theme` is used to determine what fonts and
|
/// highlighted code. A `Theme` is used to determine what fonts and
|
||||||
/// colors to use for the various tokens.
|
/// colors to use for the various tokens.
|
||||||
public struct AttributedStringOutputFormat: OutputFormat {
|
public struct AttributedStringOutputFormat: OutputFormat {
|
||||||
public var theme: Theme
|
public var theme: Theme
|
||||||
|
|
||||||
public init(theme: Theme) {
|
public init(theme: Theme) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
}
|
}
|
||||||
|
|
||||||
public func makeBuilder() -> Builder {
|
public func makeBuilder() -> Builder {
|
||||||
return Builder(theme: theme)
|
return Builder(theme: theme)
|
||||||
}
|
}
|
||||||
@ -28,32 +32,33 @@ public extension AttributedStringOutputFormat {
|
|||||||
private let theme: Theme
|
private let theme: Theme
|
||||||
private lazy var font = loadFont()
|
private lazy var font = loadFont()
|
||||||
private var string = NSMutableAttributedString()
|
private var string = NSMutableAttributedString()
|
||||||
|
|
||||||
fileprivate init(theme: Theme) {
|
fileprivate init(theme: Theme) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func addToken(_ token: String, ofType type: TokenType) {
|
public mutating func addToken(_ token: String, ofType type: TokenType) {
|
||||||
let color = theme.tokenColors[type] ?? Color(red: 1, green: 1, blue: 1)
|
let color = theme.tokenColors[type] ?? Color(red: 1, green: 1, blue: 1)
|
||||||
string.append(token, font: font, color: color)
|
string.append(token, font: font, color: color)
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func addPlainText(_ text: String) {
|
public mutating func addPlainText(_ text: String) {
|
||||||
string.append(text, font: font, color: theme.plainTextColor)
|
string.append(text, font: font, color: theme.plainTextColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func addWhitespace(_ whitespace: String) {
|
public mutating func addWhitespace(_ whitespace: String) {
|
||||||
let color = Color(red: 1, green: 1, blue: 1)
|
let color = Color(red: 1, green: 1, blue: 1)
|
||||||
string.append(whitespace, font: font, color: color)
|
string.append(whitespace, font: font, color: color)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func build() -> NSAttributedString {
|
public func build() -> NSAttributedString {
|
||||||
return NSAttributedString(attributedString: string)
|
return NSAttributedString(attributedString: string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
private mutating func loadFont() -> NSFont {
|
private mutating func loadFont() -> NSFont {
|
||||||
let size = CGFloat(theme.font.size)
|
let size = CGFloat(theme.font.size)
|
||||||
|
|
||||||
switch theme.font.resource {
|
switch theme.font.resource {
|
||||||
case .system:
|
case .system:
|
||||||
return .defaultFont(ofSize: size)
|
return .defaultFont(ofSize: size)
|
||||||
@ -61,13 +66,26 @@ public extension AttributedStringOutputFormat {
|
|||||||
guard let font = NSFont.loaded(from: path, size: size) else {
|
guard let font = NSFont.loaded(from: path, size: size) else {
|
||||||
return .defaultFont(ofSize: size)
|
return .defaultFont(ofSize: size)
|
||||||
}
|
}
|
||||||
|
|
||||||
return font
|
return font
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
private mutating func loadFont() -> UIFont {
|
||||||
|
|
||||||
|
let size = CGFloat(theme.font.size)
|
||||||
|
let font = UIFont.defaultFont(ofSize: size)
|
||||||
|
return font
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
private extension NSMutableAttributedString {
|
private extension NSMutableAttributedString {
|
||||||
func append(_ string: String, font: NSFont, color: Color) {
|
func append(_ string: String, font: NSFont, color: Color) {
|
||||||
let color = NSColor(
|
let color = NSColor(
|
||||||
@ -76,12 +94,12 @@ private extension NSMutableAttributedString {
|
|||||||
blue: CGFloat(color.blue),
|
blue: CGFloat(color.blue),
|
||||||
alpha: CGFloat(color.alpha)
|
alpha: CGFloat(color.alpha)
|
||||||
)
|
)
|
||||||
|
|
||||||
let attributedString = NSAttributedString(string: string, attributes: [
|
let attributedString = NSAttributedString(string: string, attributes: [
|
||||||
.foregroundColor: color,
|
.foregroundColor: color,
|
||||||
.font: font
|
.font: font
|
||||||
])
|
])
|
||||||
|
|
||||||
append(attributedString)
|
append(attributedString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,21 +112,52 @@ private extension NSFont {
|
|||||||
.cfurlposixPathStyle,
|
.cfurlposixPathStyle,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
guard let font = url.flatMap(CGDataProvider.init).flatMap(CGFont.init) else {
|
guard let font = url.flatMap(CGDataProvider.init).flatMap(CGFont.init) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return CTFontCreateWithGraphicsFont(font, size, nil, nil)
|
return CTFontCreateWithGraphicsFont(font, size, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func defaultFont(ofSize size: CGFloat) -> NSFont {
|
static func defaultFont(ofSize size: CGFloat) -> NSFont {
|
||||||
guard let courier = loaded(from: "/Library/Fonts/Courier New.ttf", size: size) else {
|
guard let courier = loaded(from: "/Library/Fonts/Courier New.ttf", size: size) else {
|
||||||
return .systemFont(ofSize: size)
|
return .systemFont(ofSize: size)
|
||||||
}
|
}
|
||||||
|
|
||||||
return courier
|
return courier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
private extension NSMutableAttributedString {
|
||||||
|
func append(_ string: String, font: UIFont, color: Color) {
|
||||||
|
let color = UIColor(
|
||||||
|
red: CGFloat(color.red),
|
||||||
|
green: CGFloat(color.green),
|
||||||
|
blue: CGFloat(color.blue),
|
||||||
|
alpha: CGFloat(color.alpha)
|
||||||
|
)
|
||||||
|
|
||||||
|
let attributedString = NSAttributedString(string: string, attributes: [
|
||||||
|
.foregroundColor: color,
|
||||||
|
.font: font
|
||||||
|
])
|
||||||
|
|
||||||
|
append(attributedString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension UIFont {
|
||||||
|
|
||||||
|
static func defaultFont(ofSize size: CGFloat) -> UIFont {
|
||||||
|
guard let menlo = UIFont(name: "Menlo-Regular", size: size) else {
|
||||||
|
return .systemFont(ofSize: size)
|
||||||
|
}
|
||||||
|
|
||||||
|
return menlo
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user