@@ -14,10 +14,22 @@
Loading
14 14
// MARK: - Properties
15 15
16 16
public extension NSAttributedString {
17 -
    #if os(iOS)
18 -
    /// SwifterSwift: Bolded string.
17 +
    /// SwifterSwift: Bolded string using the system font.
18 +
    #if !os(Linux)
19 19
    var bolded: NSAttributedString {
20 -
        return applying(attributes: [.font: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)])
20 +
        guard !string.isEmpty else { return self }
21 +
22 +
        let pointSize: CGFloat
23 +
        if let font = attribute(.font, at: 0, effectiveRange: nil) as? Font {
24 +
            pointSize = font.pointSize
25 +
        } else {
26 +
            #if os(tvOS) || os(watchOS)
27 +
            pointSize = Font.preferredFont(forTextStyle: .headline).pointSize
28 +
            #else
29 +
            pointSize = Font.systemFontSize
30 +
            #endif
31 +
        }
32 +
        return applying(attributes: [.font: Font.boldSystemFont(ofSize: pointSize)])
21 33
    }
22 34
    #endif
23 35
@@ -28,45 +40,53 @@
Loading
28 40
    }
29 41
    #endif
30 42
31 -
    #if os(iOS)
32 -
    /// SwifterSwift: Italicized string.
43 +
    #if canImport(UIKit)
44 +
    /// SwifterSwift: Italicized string using the system font.
33 45
    var italicized: NSAttributedString {
34 -
        return applying(attributes: [.font: UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)])
46 +
        guard !string.isEmpty else { return self }
47 +
48 +
        let pointSize: CGFloat
49 +
        if let font = attribute(.font, at: 0, effectiveRange: nil) as? UIFont {
50 +
            pointSize = font.pointSize
51 +
        } else {
52 +
            #if os(tvOS) || os(watchOS)
53 +
            pointSize = UIFont.preferredFont(forTextStyle: .headline).pointSize
54 +
            #else
55 +
            pointSize = UIFont.systemFontSize
56 +
            #endif
57 +
        }
58 +
        return applying(attributes: [.font: UIFont.italicSystemFont(ofSize: pointSize)])
35 59
    }
36 60
    #endif
37 61
38 62
    #if !os(Linux)
39 63
    /// SwifterSwift: Struckthrough string.
40 64
    var struckthrough: NSAttributedString {
41 -
        return applying(attributes: [.strikethroughStyle: NSNumber(value: NSUnderlineStyle.single.rawValue as Int)])
65 +
        return applying(attributes: [.strikethroughStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)])
42 66
    }
43 67
    #endif
44 68
45 -
    #if !os(Linux)
46 69
    /// SwifterSwift: Dictionary of the attributes applied across the whole string
47 -
    var attributes: [NSAttributedString.Key: Any] {
70 +
    var attributes: [Key: Any] {
48 71
        guard length > 0 else { return [:] }
49 72
        return attributes(at: 0, effectiveRange: nil)
50 73
    }
51 -
    #endif
52 74
}
53 75
54 76
// MARK: - Methods
55 77
56 78
public extension NSAttributedString {
57 -
    #if !os(Linux)
58 79
    /// SwifterSwift: Applies given attributes to the new instance of NSAttributedString initialized with self object
59 80
    ///
60 81
    /// - Parameter attributes: Dictionary of attributes
61 82
    /// - Returns: NSAttributedString with applied attributes
62 -
    func applying(attributes: [NSAttributedString.Key: Any]) -> NSAttributedString {
63 -
        let copy = NSMutableAttributedString(attributedString: self)
64 -
        let range = (string as NSString).range(of: string)
65 -
        copy.addAttributes(attributes, range: range)
83 +
    func applying(attributes: [Key: Any]) -> NSAttributedString {
84 +
        guard !string.isEmpty else { return self }
66 85
86 +
        let copy = NSMutableAttributedString(attributedString: self)
87 +
        copy.addAttributes(attributes, range: NSRange(0..<length))
67 88
        return copy
68 89
    }
69 -
    #endif
70 90
71 91
    #if canImport(AppKit) || canImport(UIKit)
72 92
    /// SwifterSwift: Add color to NSAttributedString.
@@ -78,7 +98,6 @@
Loading
78 98
    }
79 99
    #endif
80 100
81 -
    #if !os(Linux)
82 101
    /// SwifterSwift: Apply attributes to substrings matching a regular expression
83 102
    ///
84 103
    /// - Parameters:
@@ -86,7 +105,7 @@
Loading
86 105
    ///   - pattern: a regular expression to target
87 106
    ///   - options: The regular expression options that are applied to the expression during matching. See NSRegularExpression.Options for possible values.
88 107
    /// - Returns: An NSAttributedString with attributes applied to substrings matching the pattern
89 -
    func applying(attributes: [NSAttributedString.Key: Any],
108 +
    func applying(attributes: [Key: Any],
90 109
                  toRangesMatching pattern: String,
91 110
                  options: NSRegularExpression.Options = []) -> NSAttributedString {
92 111
        guard let pattern = try? NSRegularExpression(pattern: pattern, options: options) else { return self }
@@ -107,13 +126,12 @@
Loading
107 126
    ///   - attributes: Dictionary of attributes
108 127
    ///   - target: a subsequence string for the attributes to be applied to
109 128
    /// - Returns: An NSAttributedString with attributes applied on the target string
110 -
    func applying<T: StringProtocol>(attributes: [NSAttributedString.Key: Any],
129 +
    func applying<T: StringProtocol>(attributes: [Key: Any],
111 130
                                     toOccurrencesOf target: T) -> NSAttributedString {
112 131
        let pattern = "\\Q\(target)\\E"
113 132
114 133
        return applying(attributes: attributes, toRangesMatching: pattern)
115 134
    }
116 -
    #endif
117 135
}
118 136
119 137
// MARK: - Operators

@@ -1168,14 +1168,6 @@
Loading
1168 1168
// MARK: - NSAttributedString
1169 1169
1170 1170
public extension String {
1171 -
    #if canImport(UIKit)
1172 -
    private typealias Font = UIFont
1173 -
    #endif
1174 -
1175 -
    #if canImport(AppKit) && !targetEnvironment(macCatalyst)
1176 -
    private typealias Font = NSFont
1177 -
    #endif
1178 -
1179 1171
    #if os(iOS) || os(macOS)
1180 1172
    /// SwifterSwift: Bold string.
1181 1173
    var bold: NSAttributedString {
Files Coverage
Sources/SwifterSwift 92.80%
Project Totals (100 files) 92.80%
1
codecov:
2
  token: 9c92b00a-43e8-4dd3-b455-196052f16f86
3

4
coverage:
5
  precision: 2
6
  round: down
7
  range: 70...100
8

9
  status:
10
    project: true
11
    patch: true
12
    changes: true
13

14
  ignore:
15
    - "Sources/SwifterSwift/Deprecated/*"
16
    - "Sources/SwifterSwift/*/Deprecated/*"
17
    - "Tests/**/*"
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading