| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 
 | // https://swift.gg/2019/10/18/swift5-stringinterpolation-part2/struct AttrString {
 let attributedString: NSAttributedString
 }
 
 extension AttrString: ExpressibleByStringLiteral {
 init(stringLiteral: String) {
 self.attributedString = NSAttributedString(string: stringLiteral)
 }
 }
 
 extension AttrString: CustomStringConvertible {
 var description: String {
 return String(describing: self.attributedString)
 }
 }
 
 extension AttrString: ExpressibleByStringInterpolation {
 init(stringInterpolation: StringInterpolation) {
 self.attributedString = NSAttributedString(attributedString: stringInterpolation.attributedString)
 }
 
 struct StringInterpolation: StringInterpolationProtocol {
 var attributedString: NSMutableAttributedString
 
 init(literalCapacity: Int, interpolationCount: Int) {
 self.attributedString = NSMutableAttributedString()
 }
 
 func appendLiteral(_ literal: String) {
 let astr = NSAttributedString(string: literal)
 self.attributedString.append(astr)
 }
 
 func appendInterpolation(_ string: String, attributes: [NSAttributedString.Key: Any]) {
 let astr = NSAttributedString(string: string, attributes: attributes)
 self.attributedString.append(astr)
 }
 }
 }
 
 extension AttrString {
 struct Style {
 let attributes: [NSAttributedString.Key: Any]
 static func font(_ font: UIFont) -> Style {
 return Style(attributes: [.font: font])
 }
 static func color(_ color: UIColor) -> Style {
 return Style(attributes: [.foregroundColor: color])
 }
 static func bgColor(_ color: UIColor) -> Style {
 return Style(attributes: [.backgroundColor: color])
 }
 static func link(_ link: String) -> Style {
 return .link(URL(string: link)!)
 }
 static func link(_ link: URL) -> Style {
 return Style(attributes: [.link: link])
 }
 
 static let oblique = Style(attributes: [.obliqueness: 0.1])
 
 static func underline(_ color: UIColor, _ style: NSUnderlineStyle) -> Style {
 return Style(attributes: [
 .underlineColor: color,
 .underlineStyle: style.rawValue
 ])
 }
 static func alignment(_ alignment: NSTextAlignment) -> Style {
 let ps = NSMutableParagraphStyle()
 ps.alignment = alignment
 return Style(attributes: [.paragraphStyle: ps])
 }
 }
 }
 
 extension AttrString.StringInterpolation {
 func appendInterpolation(_ string: String, _ style: AttrString.Style...) {
 var attrs: [NSAttributedString.Key: Any] = [:]
 style.forEach { attrs.merge($0.attributes, uniquingKeysWith: {$1}) }
 let astr = NSAttributedString(string: string, attributes: attrs)
 self.attributedString.append(astr)
 }
 }
 
 extension AttrString.StringInterpolation {
 func appendInterpolation(image: UIImage, scale: CGFloat = 1.0) {
 let attachment = NSTextAttachment()
 if let cgImage = image.cgImage {
 attachment.image = UIImage(cgImage: cgImage, scale: scale, orientation: .left)
 self.attributedString.append(NSAttributedString(attachment: attachment))
 }
 }
 }
 
 extension AttrString.StringInterpolation {
 func appendInterpolation(wrap string: AttrString, _ style: AttrString.Style...) {
 var attrs: [NSAttributedString.Key: Any] = [:]
 style.forEach { attrs.merge($0.attributes, uniquingKeysWith: {$1}) }
 let mas = NSMutableAttributedString(attributedString: string.attributedString)
 let fullRange = NSRange(mas.string.startIndex..<mas.string.endIndex, in: mas.string)
 mas.addAttributes(attrs, range: fullRange)
 self.attributedString.append(mas)
 }
 }
 
 |