Skip to content

Commit 73b2b2d

Browse files
committed
#45 Better documentation
1 parent 3f72102 commit 73b2b2d

File tree

6 files changed

+92
-22
lines changed

6 files changed

+92
-22
lines changed

ExampleiOS/ViewController.swift

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,7 @@ class ViewController: UIViewController {
1717
override func viewDidLoad() {
1818
super.viewDidLoad()
1919

20-
let patternText = "[A-Z0-9a-z._%+]+@[A-Za-z0-9.]+\\.[A-Za-z]{2,4}"
21-
let bodyHTML = "daniele [email protected] ciao ciao"
22-
23-
let baseStyle = Style {
24-
$0.font = UIFont.boldSystemFont(ofSize: 12)
25-
}
26-
27-
let highlightedStyle: StyleRegEx = StyleRegEx(base: baseStyle, pattern: patternText) {
28-
$0.font = UIFont.systemFont(ofSize: 40, weight: .bold)
29-
$0.color = UIColor.red
30-
}!
31-
self.textView?.attributedText = bodyHTML.set(style: highlightedStyle)
32-
33-
34-
/*let bodyHTML = try! String(contentsOfFile: Bundle.main.path(forResource: "file", ofType: "txt")!)
20+
let bodyHTML = try! String(contentsOfFile: Bundle.main.path(forResource: "file", ofType: "txt")!)
3521

3622
let headerStyle = Style {
3723
$0.font = UIFont.boldSystemFont(ofSize: self.baseFontSize * 1.15)
@@ -77,6 +63,6 @@ class ViewController: UIViewController {
7763
self.textView?.attributedText = bodyHTML.set(style: style)
7864
if #available(iOS 10.0, *) {
7965
self.textView?.adjustsFontForContentSizeCategory = true
80-
}*/
66+
}
8167
}
8268
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// URLConvertible.swift
3+
// SwiftRichString
4+
//
5+
// Created by dan on 19/01/2019.
6+
// Copyright © 2019 SwiftRichString. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// Dynamic tag support protocol
12+
public protocol DynamicTagComposable {
13+
func dynamicValueFromTag(_ tag: StyleGroup.TagAttribute?) -> Any?
14+
}
15+
16+
/// Dynamic value for NSAttributedKey.Link and .linkURL attribute.
17+
/// If link is wrong and cannot be transformed to `URL` instance style's `link` is not applied.
18+
///
19+
/// - url: fixed url value specified by URL instance.
20+
/// - string: fixed url string specified by a simple string.
21+
/// - tagAttribute: value of a specified tag in source html-tagged style.
22+
public enum URLRepresentable: DynamicTagComposable {
23+
case url(URL)
24+
case string(String)
25+
case tagAttribute(String)
26+
27+
public func dynamicValueFromTag(_ tag: StyleGroup.TagAttribute?) -> Any? {
28+
switch self {
29+
case .url(let url):
30+
return url
31+
case .string(let string):
32+
return URL(string: string)
33+
case .tagAttribute(let tagKey):
34+
guard let value = tag?.parameters?[tagKey] else {
35+
return nil
36+
}
37+
return URL(string: value)
38+
}
39+
}
40+
41+
42+
43+
}

Sources/SwiftRichString/Style/Style.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ public class Style: StyleProtocol {
434434

435435
/// The value of this attribute is an NSURL object (preferred) or an NSString object.
436436
/// The default value of this property is nil, indicating no link.
437-
public var linkURL: URL? {
437+
public var linkURL: URLRepresentable? {
438438
set { self.set(attribute: newValue, forKey: .link) }
439439
get { return self.get(attributeForKey: .link) }
440440
}

Sources/SwiftRichString/Style/StyleGroup.swift

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,15 @@ public class StyleGroup: StyleProtocol {
4646
public class TagAttribute {
4747
let wholeTag: String
4848
var range: NSRange
49-
50-
private(set) var isOpeningTag: Bool = false
49+
50+
/// Tag identifier
5151
private(set) var name: String = ""
5252
private(set) var paramString: String?
53+
54+
/// Is opened tag
55+
private(set) var isOpeningTag: Bool = false
56+
57+
/// Discovered parameters inside the tag
5358
private(set) var parameters: [String: String]?
5459

5560
// Should only be set to opening tags
@@ -80,7 +85,7 @@ public class StyleGroup: StyleProtocol {
8085
/// - Returns: dictionary of found paramters with their values.
8186
private func extractParametersFromTags(_ string: String) -> [String: String]? {
8287
guard let _ = string.firstIndex(of: " ") else { return nil } // no tags
83-
88+
8489
let pattern = "\\w*\\s*=\\s*\"?\\s*([\\w\\s%#\\/\\.;:_-]*)\\s*\"?.*?" // maybe shorter?
8590
guard let regex = try? NSRegularExpression(pattern: pattern, options: .dotMatchesLineSeparators) else {
8691
return nil
@@ -271,7 +276,10 @@ public class StyleGroup: StyleProtocol {
271276
let length = closingTag.range.location-location
272277
let range = NSRange(location: location, length: length)
273278
attribute.fontData?.addAttributes(to: attrStr, range: range)
274-
attrStr.addAttributes(attribute.attributes, range: range)
279+
280+
var attributes = attribute.attributes
281+
resolveDynamicAttributes(&attributes, forTag: tag)
282+
attrStr.addAttributes(attributes, range: range)
275283
}
276284
}
277285

@@ -280,6 +288,21 @@ public class StyleGroup: StyleProtocol {
280288

281289
return attrStr
282290
}
291+
292+
/// Resolve only attributes which needs to have dynamic value extracted from html-styled tag.
293+
///
294+
/// - Parameters:
295+
/// - attributes: attributes to be applied.
296+
/// - tag: tag to apply.
297+
private func resolveDynamicAttributes(_ attributes: inout [NSAttributedString.Key : Any], forTag tag: TagAttribute) {
298+
// only specific attribute keys can contain dynamic attributes
299+
let supportedDynamicKeys: Set<NSAttributedString.Key> = [NSAttributedString.Key.link]
300+
supportedDynamicKeys.forEach { key in
301+
if let composableValue = attributes[key] as? DynamicTagComposable {
302+
attributes[key] = composableValue.dynamicValueFromTag(tag)
303+
}
304+
}
305+
}
283306

284307
}
285308

SwiftRichString.xcodeproj/project.pbxproj

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,14 @@
131131
64507F3420B1912B009455BD /* OrderedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64507E7720AEF611009455BD /* OrderedDictionary.swift */; };
132132
64507F3520B1912B009455BD /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64507EBD20B18489009455BD /* Extensions.swift */; };
133133
64774AD3213E91B9008F8DC3 /* file.txt in Resources */ = {isa = PBXBuildFile; fileRef = 64774AD2213E91B9008F8DC3 /* file.txt */; };
134+
647AD64D21F3898400CF787E /* URLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647AD64C21F3898400CF787E /* URLRepresentable.swift */; };
135+
647AD64E21F3898400CF787E /* URLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647AD64C21F3898400CF787E /* URLRepresentable.swift */; };
136+
647AD64F21F3898400CF787E /* URLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647AD64C21F3898400CF787E /* URLRepresentable.swift */; };
137+
647AD65021F3898400CF787E /* URLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647AD64C21F3898400CF787E /* URLRepresentable.swift */; };
138+
647AD65121F389A400CF787E /* URLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647AD64C21F3898400CF787E /* URLRepresentable.swift */; };
139+
647AD65221F389A400CF787E /* URLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647AD64C21F3898400CF787E /* URLRepresentable.swift */; };
140+
647AD65321F389A400CF787E /* URLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647AD64C21F3898400CF787E /* URLRepresentable.swift */; };
141+
647AD65421F389A800CF787E /* URLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647AD64C21F3898400CF787E /* URLRepresentable.swift */; };
134142
648932CA209DE194000E691A /* CommonsAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648932C9209DE194000E691A /* CommonsAttributes.swift */; };
135143
648932CB209DE194000E691A /* CommonsAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648932C9209DE194000E691A /* CommonsAttributes.swift */; };
136144
648932CC209DE194000E691A /* CommonsAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648932C9209DE194000E691A /* CommonsAttributes.swift */; };
@@ -296,6 +304,7 @@
296304
64507F1720B1911B009455BD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
297305
64507F1820B1911B009455BD /* PushNotificationPayload.apns */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushNotificationPayload.apns; sourceTree = "<group>"; };
298306
64774AD2213E91B9008F8DC3 /* file.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = file.txt; sourceTree = "<group>"; };
307+
647AD64C21F3898400CF787E /* URLRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRepresentable.swift; sourceTree = "<group>"; };
299308
648932C9209DE194000E691A /* CommonsAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonsAttributes.swift; sourceTree = "<group>"; };
300309
648932D3209DE44E000E691A /* FontConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontConvertible.swift; sourceTree = "<group>"; };
301310
648932DC209DE474000E691A /* ExampleiOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleiOS.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -486,6 +495,7 @@
486495
64893308209DE7C5000E691A /* ColorConvertible.swift */,
487496
6489332420A0CA76000E691A /* FontInfoAttribute.swift */,
488497
D53F4E7A21F03E690085D26F /* DynamicText.swift */,
498+
647AD64C21F3898400CF787E /* URLRepresentable.swift */,
489499
);
490500
path = Attributes;
491501
sourceTree = "<group>";
@@ -1065,6 +1075,7 @@
10651075
64507EA420B05015009455BD /* AttributedString+Ext.swift in Sources */,
10661076
64893309209DE7C5000E691A /* ColorConvertible.swift in Sources */,
10671077
64507E8620AF3609009455BD /* String+Subscript.swift in Sources */,
1078+
647AD64D21F3898400CF787E /* URLRepresentable.swift in Sources */,
10681079
64507EAC20B056FB009455BD /* FontData.swift in Sources */,
10691080
648932D4209DE44E000E691A /* FontConvertible.swift in Sources */,
10701081
64507E7120AEF12C009455BD /* AssociatedValues.swift in Sources */,
@@ -1100,6 +1111,7 @@
11001111
64507EA620B05015009455BD /* AttributedString+Ext.swift in Sources */,
11011112
6489330B209DE7C5000E691A /* ColorConvertible.swift in Sources */,
11021113
64507E8820AF3609009455BD /* String+Subscript.swift in Sources */,
1114+
647AD64F21F3898400CF787E /* URLRepresentable.swift in Sources */,
11031115
64507EAE20B056FB009455BD /* FontData.swift in Sources */,
11041116
648932D6209DE44E000E691A /* FontConvertible.swift in Sources */,
11051117
64507E7320AEF12C009455BD /* AssociatedValues.swift in Sources */,
@@ -1127,6 +1139,7 @@
11271139
64507EA720B05015009455BD /* AttributedString+Ext.swift in Sources */,
11281140
6489330C209DE7C5000E691A /* ColorConvertible.swift in Sources */,
11291141
64507E8920AF3609009455BD /* String+Subscript.swift in Sources */,
1142+
647AD65021F3898400CF787E /* URLRepresentable.swift in Sources */,
11301143
64507EAF20B056FB009455BD /* FontData.swift in Sources */,
11311144
648932D7209DE44E000E691A /* FontConvertible.swift in Sources */,
11321145
64507E7420AEF12C009455BD /* AssociatedValues.swift in Sources */,
@@ -1154,6 +1167,7 @@
11541167
64507EA520B05015009455BD /* AttributedString+Ext.swift in Sources */,
11551168
6489330A209DE7C5000E691A /* ColorConvertible.swift in Sources */,
11561169
64507E8720AF3609009455BD /* String+Subscript.swift in Sources */,
1170+
647AD64E21F3898400CF787E /* URLRepresentable.swift in Sources */,
11571171
64507EAD20B056FB009455BD /* FontData.swift in Sources */,
11581172
648932D5209DE44E000E691A /* FontConvertible.swift in Sources */,
11591173
64507E7220AEF12C009455BD /* AssociatedValues.swift in Sources */,
@@ -1176,6 +1190,7 @@
11761190
files = (
11771191
64507EE020B18F0F009455BD /* ViewController.swift in Sources */,
11781192
64507EEA20B18F20009455BD /* StyleProtocol.swift in Sources */,
1193+
647AD65321F389A400CF787E /* URLRepresentable.swift in Sources */,
11791194
64507EF120B18F20009455BD /* AttributedString+Ext.swift in Sources */,
11801195
64507EDE20B18F0F009455BD /* AppDelegate.swift in Sources */,
11811196
D53F4E8021F03F240085D26F /* DynamicText.swift in Sources */,
@@ -1210,6 +1225,7 @@
12101225
64507F2420B1912B009455BD /* StyleProtocol.swift in Sources */,
12111226
64507F3220B1912B009455BD /* FontInfoAttribute.swift in Sources */,
12121227
64507F2D20B1912B009455BD /* UIKit+Extras.swift in Sources */,
1228+
647AD65421F389A800CF787E /* URLRepresentable.swift in Sources */,
12131229
64507F3020B1912B009455BD /* FontConvertible.swift in Sources */,
12141230
64507F2E20B1912B009455BD /* FontData.swift in Sources */,
12151231
64507F2F20B1912B009455BD /* CommonsAttributes.swift in Sources */,
@@ -1235,6 +1251,7 @@
12351251
files = (
12361252
64507EA820B05015009455BD /* AttributedString+Ext.swift in Sources */,
12371253
648932EE209DE47C000E691A /* CommonsAttributes.swift in Sources */,
1254+
647AD65121F389A400CF787E /* URLRepresentable.swift in Sources */,
12381255
64507E9120AF3A9C009455BD /* StyleProtocol.swift in Sources */,
12391256
64893322209DED04000E691A /* StyleGroup.swift in Sources */,
12401257
D53F4E8221F03F250085D26F /* DynamicText.swift in Sources */,
@@ -1264,6 +1281,7 @@
12641281
files = (
12651282
64893305209DE6CD000E691A /* CommonsAttributes.swift in Sources */,
12661283
64893323209DED04000E691A /* StyleGroup.swift in Sources */,
1284+
647AD65221F389A400CF787E /* URLRepresentable.swift in Sources */,
12671285
64507E7620AEF12C009455BD /* AssociatedValues.swift in Sources */,
12681286
648932FA209DE6C5000E691A /* ViewController.swift in Sources */,
12691287
D53F4E8121F03F240085D26F /* DynamicText.swift in Sources */,

SwiftRichString.xcodeproj/xcuserdata/daniele.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
ignoreCount = "0"
1111
continueAfterRunningActions = "No"
1212
filePath = "Sources/SwiftRichString/Style/Style.swift"
13-
timestampString = "569606555.43208"
13+
timestampString = "569615006.0644979"
1414
startingColumnNumber = "9223372036854775807"
1515
endingColumnNumber = "9223372036854775807"
1616
startingLineNumber = "302"

0 commit comments

Comments
 (0)