| 1 | import Foundation |
| 2 | #if os(macOS) |
| 3 | import AppKit |
| 4 | #else |
| 5 | import UIKit |
| 6 | #endif |
| 7 | |
| 8 | extension NSAttributedString.Key { static let docsCodeStart = NSAttributedString.Key("OficinaDocsCodeStart") } |
| 9 | |
| 10 | /// Inline decoration uses glyph advances, never extra characters: CRDT and |
| 11 | /// clipboard offsets continue to refer to the authored text. |
| 12 | @MainActor enum DocumentInlineCode { |
| 13 | static func apply(to output: NSMutableAttributedString) { |
| 14 | var spans: [NSRange] = [] |
| 15 | output.enumerateAttribute(.docsMarks, in: NSRange(location: 0, length: output.length)) { value, range, _ in |
| 16 | guard let data = value as? Data, |
| 17 | let marks = try? JSONDecoder().decode([String: JSONValue].self, from: data), marks["code"] != nil else { return } |
| 18 | if let last = spans.last, NSMaxRange(last) == range.location { spans[spans.count - 1] = NSUnionRange(last, range) } |
| 19 | else { spans.append(range) } |
| 20 | } |
| 21 | for range in spans where range.length > 0 { |
| 22 | guard let font = output.attribute(.font, at: range.location, effectiveRange: nil) as? DocsPlatformFont else { continue } |
| 23 | let padding = font.pointSize * 0.35 |
| 24 | let paragraph = (output.string as NSString).paragraphRange(for: NSRange(location: range.location, length: 0)) |
| 25 | output.addAttribute(.docsCodeStart, value: padding, |
| 26 | range: (output.string as NSString).rangeOfComposedCharacterSequence(at: range.location)) |
| 27 | if paragraph.location != range.location && range.location > 0 { |
| 28 | output.addAttribute(.kern, value: padding, range: (output.string as NSString).rangeOfComposedCharacterSequence(at: range.location - 1)) |
| 29 | } |
| 30 | output.addAttribute(.kern, value: padding, range: (output.string as NSString).rangeOfComposedCharacterSequence(at: NSMaxRange(range) - 1)) |
| 31 | #if os(macOS) |
| 32 | output.addAttribute(.backgroundColor, value: NSColor(white: 240.0 / 255, alpha: 1), range: range) |
| 33 | #else |
| 34 | output.addAttribute(.backgroundColor, value: UIColor(white: 240.0 / 255, alpha: 1), range: range) |
| 35 | #endif |
| 36 | } |
| 37 | } |
| 38 | } |
| 39 | |