Last active
February 28, 2018 09:56
-
-
Save bagpack/c52795edc1d3a81cd12ea867cf2f1db1 to your computer and use it in GitHub Desktop.
<color=#FF00FF>kappa</color> -> NSAttributedString
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class RichTextParser { | |
class func parse(text: String) throws -> NSAttributedString { | |
let colorPattern = "<color=#([\\w]{6})>(.+?)</color>" | |
let attributedText = NSMutableAttributedString() | |
do { | |
let nsText = (text as NSString) | |
let regex = try NSRegularExpression(pattern: colorPattern, options: []) | |
let matches = regex.matches(in: text, options: [], range: NSRange(location: 0, length: nsText.length)) | |
var currentIndex = 0 | |
for (index, match) in matches.enumerated() { | |
let range = match.range(at: 0) | |
let rgb = nsText.substring(with: match.range(at: 1)) | |
let text = nsText.substring(with: match.range(at: 2)) | |
let myRange = NSRange(location: currentIndex, length: range.location - currentIndex) | |
let rgbValues = parseRGB(rgb: rgb) | |
attributedText.append(NSAttributedString(string: nsText.substring(with: myRange))) | |
attributedText.append(NSAttributedString( | |
string: text, | |
attributes: [ | |
NSAttributedStringKey.foregroundColor: UIColor(red: rgbValues.red / 255.0, green: rgbValues.green / 255.0, blue: rgbValues.blue / 255.0, alpha: 1.0) | |
])) | |
currentIndex = range.location + range.length | |
if index == matches.count - 1 { | |
attributedText.append( | |
NSAttributedString(string: nsText.substring(with: NSRange(location: currentIndex, length: nsText.length - currentIndex)))) | |
} | |
} | |
return attributedText | |
} catch let e { | |
throw e | |
} | |
} | |
private class func parseRGB(rgb: String) -> (red: CGFloat, green: CGFloat, blue: CGFloat) { | |
let red = Int(rgb[rgb.index(rgb.startIndex, offsetBy: 0)..<rgb.index(rgb.startIndex, offsetBy: 2)], radix: 16) ?? 0 | |
let green = Int(rgb[rgb.index(rgb.startIndex, offsetBy: 2)..<rgb.index(rgb.startIndex, offsetBy: 4)], radix: 16) ?? 0 | |
let blue = Int(rgb[rgb.index(rgb.startIndex, offsetBy: 4)..<rgb.index(rgb.startIndex, offsetBy: 6)], radix: 16) ?? 0 | |
return (red: CGFloat(red), | |
green: CGFloat(green), | |
blue: CGFloat(blue)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Swift 4 support.