Skip to content

Instantly share code, notes, and snippets.

@bagpack
Last active February 28, 2018 09:56
Show Gist options
  • Save bagpack/c52795edc1d3a81cd12ea867cf2f1db1 to your computer and use it in GitHub Desktop.
Save bagpack/c52795edc1d3a81cd12ea867cf2f1db1 to your computer and use it in GitHub Desktop.
<color=#FF00FF>kappa</color> -> NSAttributedString
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))
}
}
@bagpack
Copy link
Author

bagpack commented Feb 28, 2018

Swift 4 support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment