Skip to content

Commit 3f72102

Browse files
committed
#45 Extract parameters from tag content of TagAttribute struct.
1 parent 1a34c2d commit 3f72102

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

Sources/SwiftRichString/Style/StyleGroup.swift

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ public class StyleGroup: StyleProtocol {
4343
public var fontData: FontData? = nil
4444

4545
/// TagAttribute represent a single tag in a source string after the text is parsed.
46-
private class TagAttribute {
46+
public class TagAttribute {
4747
let wholeTag: String
4848
var range: NSRange
4949

5050
private(set) var isOpeningTag: Bool = false
5151
private(set) var name: String = ""
5252
private(set) var paramString: String?
53-
53+
private(set) var parameters: [String: String]?
54+
5455
// Should only be set to opening tags
5556
var endingTagIndex: Int?
5657

@@ -63,13 +64,43 @@ public class StyleGroup: StyleProtocol {
6364
paramString = strippedTag.removing(prefix: name).trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
6465
if paramString?.count == 0 { paramString = nil }
6566
}
67+
68+
self.parameters = extractParametersFromTags(wholeTag)
6669
}
6770

6871
init(wholeTag: String, range: NSRange) {
6972
self.wholeTag = wholeTag
7073
self.range = range
7174
processWholeTag()
7275
}
76+
77+
/// Extract parameters from each tag.
78+
///
79+
/// - Parameter string: whole tag string.
80+
/// - Returns: dictionary of found paramters with their values.
81+
private func extractParametersFromTags(_ string: String) -> [String: String]? {
82+
guard let _ = string.firstIndex(of: " ") else { return nil } // no tags
83+
84+
let pattern = "\\w*\\s*=\\s*\"?\\s*([\\w\\s%#\\/\\.;:_-]*)\\s*\"?.*?" // maybe shorter?
85+
guard let regex = try? NSRegularExpression(pattern: pattern, options: .dotMatchesLineSeparators) else {
86+
return nil
87+
}
88+
89+
let matches = regex.matches(in: string,
90+
options: NSRegularExpression.MatchingOptions.reportCompletion,
91+
range: NSRange(location: 0, length: (string as NSString).length))
92+
93+
return matches.reduce([:]) { (paramDict, match) in
94+
var paramDict = paramDict
95+
let block = (wholeTag as NSString).substring(with: match.range)
96+
if let dividerIndex = block.firstIndex(of: "=") {
97+
let key = String(block[block.startIndex..<dividerIndex])
98+
let value = String(block[block.index(dividerIndex, offsetBy: 2)..<block.index(block.endIndex, offsetBy: -1)])
99+
paramDict?[key] = value
100+
}
101+
return paramDict
102+
}
103+
}
73104
}
74105

75106
//MARK: PROPERTIES

0 commit comments

Comments
 (0)