import Highlightr import OrgSwiftUI import SwiftUI import UIKit /// Highlights `#+begin_src` blocks in org content, bridging Highlightr to `OrgCodeStyler`. /// /// Highlightr already returns an `NSAttributedString`, so this walks its color runs straight /// into an `AttributedString`. Colors are baked in, so a new instance is made per theme. @MainActor final class OrgSyntaxStyler: OrgCodeStyler { private let highlightr: Highlightr? private let supported: Set init(colorScheme: ColorScheme) { let engine = Highlightr() engine?.setTheme(to: colorScheme == .dark ? "atom-one-dark" : "xcode") highlightr = engine supported = Set(engine?.supportedLanguages() ?? []) } func highlighted(code: String, language: String?) -> AttributedString? { guard let highlightr, let language = resolvedLanguage(language) else { return nil } highlightr.theme.setCodeFont(.monospacedSystemFont(ofSize: 13, weight: .regular)) guard let attributed = highlightr.highlight(code, as: language, fastRender: true) else { return nil } return Self.attributedString(from: attributed) } private func resolvedLanguage(_ raw: String?) -> String? { guard let trimmed = raw?.trimmingCharacters(in: .whitespacesAndNewlines).lowercased(), !trimmed.isEmpty else { return nil } let mapped = Self.aliases[trimmed] ?? trimmed return supported.contains(mapped) ? mapped : nil } private static let aliases: [String: String] = [ "js": "javascript", "jsx": "javascript", "ts": "typescript", "tsx": "typescript", "py": "python", "rb": "ruby", "rs": "rust", "sh": "bash", "shell": "bash", "zsh": "bash", "yml": "yaml", "c++": "cpp", "cc": "cpp", "kt": "kotlin", "cs": "csharp", "objc": "objectivec", "objective-c": "objectivec", "html": "xml", "htm": "xml", ] /// Carry Highlightr's colors across, in a monospaced font at the block's own size. private static func attributedString(from attributed: NSAttributedString) -> AttributedString { var result = AttributedString() let range = NSRange(location: 0, length: attributed.length) attributed.enumerateAttribute(.foregroundColor, in: range) { value, subrange, _ in var fragment = AttributedString((attributed.string as NSString).substring(with: subrange)) fragment.font = .system(.footnote, design: .monospaced) if let color = value as? UIColor { fragment.foregroundColor = Color(uiColor: color) } result += fragment } return result } }