diff --git a/.travis.yml b/.travis.yml
index ed1fe7c..cb645ad 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,12 @@
language: objective-c
osx_image: xcode8
+
+env:
+ - PLATFORM=iOS CODECOV=ios DESTINATION='platform=iOS Simulator,name=iPhone 6S'
+ - PLATFORM=Mac CODECOV=osx DESTINATION='platform=OS X'
+ - PLATFORM=tvOS CODECOV=tvos DESTINATION='platform=tvOS Simulator,name=Apple TV 1080p'
+
script:
- xcodebuild -version
- - xcodebuild -project SwiftyAttributes.xcodeproj -scheme SwiftyAttributesTests -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 6" -configuration Debug ONLY_ACTIVE_ARCH=YES -enableCodeCoverage YES test
- - bash <(curl -s https://codecov.io/bash) -cF ios
\ No newline at end of file
+ - xcodebuild -project SwiftyAttributes.xcodeproj -scheme "SwiftyAttributes" -destination "$DESTINATION" -configuration Debug -enableCodeCoverage YES CODE_SIGNING_REQUIRED=NO test
+ - bash <(curl -s https://codecov.io/bash) -cF "$CODECOV"
diff --git a/ExampleApp-iOS/ViewController.swift b/ExampleApp-iOS/ViewController.swift
index 1e31025..c8757bc 100644
--- a/ExampleApp-iOS/ViewController.swift
+++ b/ExampleApp-iOS/ViewController.swift
@@ -15,9 +15,9 @@ class ViewController: UITableViewController {
private let attributedStrings: [NSAttributedString] = [
{
- let attachment = NSTextAttachment()
+ let attachment = TextAttachment()
attachment.image = UIImage(named: "Star")
- let str = NSMutableAttributedString(string: "Attachment With Image")
+ let str = "Attachment With Image".attributedString
str.replaceCharacters(in: 10 ..< 12, with: NSAttributedString(attachment: attachment))
return str
}(),
@@ -31,7 +31,7 @@ class ViewController: UITableViewController {
"Link".withLink(URL(string: "https://google.com")!),
"Obliqueness".withObliqueness(2),
"Shadow".withShadow({
- let shadow = NSShadow()
+ let shadow = Shadow()
shadow.shadowBlurRadius = 2
shadow.shadowOffset = CGSize(width: 3, height: -4)
return shadow
diff --git a/ExampleApp-macOS/AppDelegate.swift b/ExampleApp-macOS/AppDelegate.swift
new file mode 100644
index 0000000..35a4a09
--- /dev/null
+++ b/ExampleApp-macOS/AppDelegate.swift
@@ -0,0 +1,12 @@
+//
+// AppDelegate.swift
+// ExampleApp-macOS
+//
+// Created by Eddie Kaiger on 11/26/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+import Cocoa
+
+@NSApplicationMain
+class AppDelegate: NSObject, NSApplicationDelegate { }
diff --git a/ExampleApp-macOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/ExampleApp-macOS/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..2db2b1c
--- /dev/null
+++ b/ExampleApp-macOS/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/ExampleApp-macOS/Assets.xcassets/Contents.json b/ExampleApp-macOS/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/ExampleApp-macOS/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/ExampleApp-macOS/Base.lproj/Main.storyboard b/ExampleApp-macOS/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..6cab678
--- /dev/null
+++ b/ExampleApp-macOS/Base.lproj/Main.storyboard
@@ -0,0 +1,750 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ExampleApp-macOS/Info.plist b/ExampleApp-macOS/Info.plist
new file mode 100644
index 0000000..9d1a361
--- /dev/null
+++ b/ExampleApp-macOS/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ $(MACOSX_DEPLOYMENT_TARGET)
+ NSHumanReadableCopyright
+ Copyright © 2016 Eddie Kaiger. All rights reserved.
+ NSMainStoryboardFile
+ Main
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/ExampleApp-macOS/ViewController.swift b/ExampleApp-macOS/ViewController.swift
new file mode 100644
index 0000000..2e01c92
--- /dev/null
+++ b/ExampleApp-macOS/ViewController.swift
@@ -0,0 +1,72 @@
+//
+// ViewController.swift
+// ExampleApp-macOS
+//
+// Created by Eddie Kaiger on 11/26/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+import Cocoa
+import SwiftyAttributes
+
+class ViewController: NSViewController {
+
+ fileprivate let attributedStrings: [NSAttributedString] = [
+ {
+ let attachment = TextAttachment()
+ attachment.image = NSImage(named: "Star")!
+ let str = "Attachment With Image".attributedString
+ str.replaceCharacters(in: 10 ..< 12, with: NSAttributedString(attachment: attachment))
+ return str
+ }(),
+ "Baseline Offset".withBaselineOffset(8.5),
+ "Background Color".withBackgroundColor(.blue),
+ "Expansion".withExpansion(0.8),
+ "Font".withFont(.boldSystemFont(ofSize: 20)),
+ "Kern".withKern(5.1),
+ "Default Ligatures".withLigatures(.default),
+ "No Ligatures".withLigatures(.none),
+ "Link".withLink(URL(string: "https://google.com")!),
+ "Obliqueness".withObliqueness(2),
+ "Shadow".withShadow({
+ let shadow = Shadow()
+ shadow.shadowBlurRadius = 2
+ shadow.shadowOffset = CGSize(width: 3, height: -4)
+ return shadow
+ }()),
+ "Stroke Color".withStrokeColor(.orange).withStrokeWidth(1),
+ "Stroke Width".withStrokeWidth(2.7),
+ "Strikethrough Style & Color".withStrikethroughColor(.green).withStrikethroughStyle(.styleDouble),
+ "Text Color".withTextColor(.brown),
+ "Text Effect".withTextEffect(.letterPressStyle),
+ "Underline Style & Color".withUnderlineColor(.red).withUnderlineStyle(.styleDouble),
+ "Writing Directions".withWritingDirections([.rightToLeftOverride]),
+ "Multiple Attributes".withAttributes([.baselineOffset(5), .font(.boldSystemFont(ofSize: 20)), .kern(4), .underlineStyle(.styleSingle), .underlineColor(.magenta), .strokeColor(.orange), .strokeWidth(3), .strikethroughColor(.green), .strikethroughStyle(.styleSingle), .backgroundColor(.yellow)]),
+ {
+ let str = "Partial Range Attributes".withUnderlineStyle(.styleSingle)
+ str.addAttributes([.underlineStyle(.styleDouble), .textColor(.blue)], range: 3 ..< 8)
+ str.addAttributes([.strikethroughStyle(.styleThick), .strikethroughColor(.purple)], range: 16 ..< 22)
+ str.setAttributes([.textColor(.red)], range: 22 ..< 24)
+ return str
+ }()
+ ]
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+
+ }
+
+}
+
+extension ViewController: NSTableViewDataSource {
+
+ func numberOfRows(in tableView: NSTableView) -> Int {
+ return attributedStrings.count
+ }
+
+ func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
+ return attributedStrings[row]
+ }
+
+}
diff --git a/README.md b/README.md
index 103658e..3dea341 100644
--- a/README.md
+++ b/README.md
@@ -94,7 +94,7 @@ Initializing attributed strings in `SwiftyAttributes` can be done several ways:
- Using the `Attribute` enum extensions:
````swift
- "Hello World".withAttributes([.underlineColor(.red), underlineStyle(.styleDouble)])
+ "Hello World".withAttributes([.underlineColor(.red), .underlineStyle(.styleDouble)])
````
- Using the `Attribute` enum in an initializer:
@@ -127,24 +127,24 @@ extension NSAttributedString {
func withAttribute(_ attribute: Attribute) -> NSMutableAttributedString
func attributedSubstring(from range: Range) -> NSAttributedString
func attribute(_ attrName: Attribute.Name, at location: Int, effectiveRange range: NSRangePointer? = nil) -> Attribute?
+ func attributes(in range: Range, options: NSAttributedString.EnumerationOptions = []) -> [([Attribute], Range)]
+ func enumerateAttributes(in enumerationRange: Range, options: NSAttributedString.EnumerationOptions = [], using block: (_ attrs: [Attribute], _ range: Range, _ stop: UnsafeMutablePointer) -> Void)
+ func enumerateAttribute(_ attrName: Attribute.Name, in enumerationRange: Range, options: NSAttributedString.EnumerationOptions = [], using block: (_ value: Any?, _ range: Range, _ stop: UnsafeMutablePointer) -> Void)
}
extension String {
+ var attributedString: NSMutableAttributedString
func withAttributes(_ attributes: [Attribute]) -> NSMutableAttributedString
func withAttribute(_ attribute: Attribute) -> NSMutableAttributedString
}
-````
-
-# Goals
+// ... and more!
-The goal of version 3.1.0 will be full support for macOS, tvOS, and watchOS as well as additional helper methods to retrieve and enumerate attributes in an attributed string.
-
-If you have suggestions and feature requests, please feel free to open up an issue.
+````
# Support
-For questions and support, please open up an issue.
+For questions, support, and suggestions, please open up an issue.
# License
diff --git a/SwiftyAttributes.podspec b/SwiftyAttributes.podspec
index 48b46d4..f4de899 100644
--- a/SwiftyAttributes.podspec
+++ b/SwiftyAttributes.podspec
@@ -2,20 +2,26 @@
Pod::Spec.new do |s|
s.name = "SwiftyAttributes"
- s.version = "3.0.0"
- s.summary = "Swift extensions that make it a breeze to work with attributed strings."
+ s.version = "3.1.0"
+ s.summary = "A Swifty API for attributed strings."
s.description = <<-DESC
- SwiftyAttributes provides extensions for the String and NSAttributedString classes that make it easier to create and modify attributed strings.
+ SwiftyAttributes provides a clean, Swifty API for dealing with NSAttributedStrings.
DESC
s.homepage = "https://github.com/eddiekaiger/SwiftyAttributes"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "Eddie Kaiger" => "eddiekaiger@gmail.com" }
- s.source = { :git => "https://github.com/eddiekaiger/SwiftyAttributes.git", :tag => "v3.0.0" }
- s.source_files = "SwiftyAttributes/*.swift"
- s.platform = :ios, '8.0'
+ s.source = { :git => "https://github.com/eddiekaiger/SwiftyAttributes.git", :tag => "v3.1.0" }
+
+ s.source_files = "SwiftyAttributes/Sources/common/*.swift"
+ s.osx.source_files = "SwiftyAttributes/Sources/macOS/*.swift"
+
+ s.ios.deployment_target = '8.0'
+ s.osx.deployment_target = '10.11'
+ s.tvos.deployment_target = '9.0'
+ s.watchos.deployment_target = '2.0'
end
diff --git a/SwiftyAttributes.xcodeproj/project.pbxproj b/SwiftyAttributes.xcodeproj/project.pbxproj
index b503d18..9112454 100644
--- a/SwiftyAttributes.xcodeproj/project.pbxproj
+++ b/SwiftyAttributes.xcodeproj/project.pbxproj
@@ -7,50 +7,72 @@
objects = {
/* Begin PBXBuildFile section */
- C00CF8F31DA6142500B6C1BB /* WritingDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00CF8F21DA6142500B6C1BB /* WritingDirection.swift */; };
- C0127C3C1DB2D5490047DF5A /* Attribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0127C3B1DB2D5490047DF5A /* Attribute.swift */; };
- C01C438D1DC472F000C49E5E /* TextEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = C01C438C1DC472F000C49E5E /* TextEffect.swift */; };
- C0335B5C1DC083A5009F9B51 /* NSAttributedString+SwiftyAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0335B5B1DC083A5009F9B51 /* NSAttributedString+SwiftyAttributes.swift */; };
- C0335B5E1DC083AE009F9B51 /* String+SwiftyAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0335B5D1DC083AE009F9B51 /* String+SwiftyAttributes.swift */; };
- C0335B601DC08409009F9B51 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0335B5F1DC08409009F9B51 /* Operators.swift */; };
- C0335B621DC086B3009F9B51 /* NSMutableAttributedString+SwiftyAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0335B611DC086B3009F9B51 /* NSMutableAttributedString+SwiftyAttributes.swift */; };
- C0335B641DC0877C009F9B51 /* WritingDirection_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0335B631DC0877C009F9B51 /* WritingDirection_Tests.swift */; };
- C0335B661DC087A3009F9B51 /* Operators_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0335B651DC087A3009F9B51 /* Operators_Tests.swift */; };
- C03658F21DC84CCA0051F06D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C03658EF1DC84B3F0051F06D /* Images.xcassets */; };
+ C027C0C91DEA0A0100953C09 /* SpellingState_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C027C0C81DEA0A0100953C09 /* SpellingState_Tests.swift */; };
+ C027C0CB1DEA452500953C09 /* Attribute+Sequence_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C027C0CA1DEA452500953C09 /* Attribute+Sequence_Tests.swift */; };
C03658FA1DC859D80051F06D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C03658F91DC859D80051F06D /* AppDelegate.swift */; };
C03658FC1DC859D80051F06D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C03658FB1DC859D80051F06D /* ViewController.swift */; };
C03658FF1DC859D80051F06D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C03658FD1DC859D80051F06D /* Main.storyboard */; };
C03659011DC859D80051F06D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C03659001DC859D80051F06D /* Assets.xcassets */; };
C03659041DC859D80051F06D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C03659021DC859D80051F06D /* LaunchScreen.storyboard */; };
C03659091DC85AE40051F06D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C03658EF1DC84B3F0051F06D /* Images.xcassets */; };
- C05C54F71DA61F4E007514C1 /* Ligatures.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05C54F61DA61F4E007514C1 /* Ligatures.swift */; };
- C08D04131DC39B5500575F98 /* NSMutableAttributedString_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C08D04121DC39B5500575F98 /* NSMutableAttributedString_Tests.swift */; };
- C08D04151DC3B16A00575F98 /* NSAttributedString_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C08D04141DC3B16A00575F98 /* NSAttributedString_Tests.swift */; };
- C0D753FB1DC5C77E00BB9754 /* TextEffect_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0D753FA1DC5C77E00BB9754 /* TextEffect_Tests.swift */; };
- C0D753FD1DC5C88900BB9754 /* Attribute_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0D753FC1DC5C88900BB9754 /* Attribute_Tests.swift */; };
- C0E211541D9EC5C000623F02 /* SwiftyAttributes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0E2114A1D9EC5C000623F02 /* SwiftyAttributes.framework */; };
- C0E211591D9EC5C000623F02 /* SwiftyAttributes_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0E211581D9EC5C000623F02 /* SwiftyAttributes_Tests.swift */; };
- C0E2115B1D9EC5C000623F02 /* SwiftyAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = C0E2114D1D9EC5C000623F02 /* SwiftyAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C05082291DFA72F700D39B3B /* Attribute+Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = C050821E1DFA72F700D39B3B /* Attribute+Sequence.swift */; };
+ C050822A1DFA72F700D39B3B /* Attribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = C050821F1DFA72F700D39B3B /* Attribute.swift */; };
+ C050822B1DFA72F700D39B3B /* AttributeName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082201DFA72F700D39B3B /* AttributeName.swift */; };
+ C050822C1DFA72F700D39B3B /* Ligatures.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082211DFA72F700D39B3B /* Ligatures.swift */; };
+ C050822D1DFA72F700D39B3B /* NSAttributedString+SwiftyAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082221DFA72F700D39B3B /* NSAttributedString+SwiftyAttributes.swift */; };
+ C050822E1DFA72F700D39B3B /* NSMutableAttributedString+SwiftyAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082231DFA72F700D39B3B /* NSMutableAttributedString+SwiftyAttributes.swift */; };
+ C050822F1DFA72F700D39B3B /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082241DFA72F700D39B3B /* Operators.swift */; };
+ C05082301DFA72F700D39B3B /* String+SwiftyAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082251DFA72F700D39B3B /* String+SwiftyAttributes.swift */; };
+ C05082311DFA72F700D39B3B /* TextEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082261DFA72F700D39B3B /* TextEffect.swift */; };
+ C05082321DFA72F700D39B3B /* VerticalGlyphForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082271DFA72F700D39B3B /* VerticalGlyphForm.swift */; };
+ C05082331DFA72F700D39B3B /* WritingDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05082281DFA72F700D39B3B /* WritingDirection.swift */; };
+ C0782E391DEAB30800E1B99F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0782E381DEAB30800E1B99F /* AppDelegate.swift */; };
+ C0782E3B1DEAB30800E1B99F /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0782E3A1DEAB30800E1B99F /* ViewController.swift */; };
+ C0782E3D1DEAB30800E1B99F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0782E3C1DEAB30800E1B99F /* Assets.xcassets */; };
+ C0782E401DEAB30800E1B99F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C0782E3E1DEAB30800E1B99F /* Main.storyboard */; };
+ C09633E01DD806F600059332 /* SwiftyAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = C09633DC1DD8056000059332 /* SwiftyAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C0DB42EC1DDED3500093A6FA /* NSAttributedString+macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DB42EB1DDED3500093A6FA /* NSAttributedString+macOS.swift */; };
+ C0E1C9541DD319D50068E85C /* SwiftyAttributes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0E1C94B1DD319D50068E85C /* SwiftyAttributes.framework */; };
+ C0E1C96A1DD31A0D0068E85C /* Attribute_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0D753FC1DC5C88900BB9754 /* Attribute_Tests.swift */; };
+ C0E1C96B1DD31A0D0068E85C /* NSMutableAttributedString_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C08D04121DC39B5500575F98 /* NSMutableAttributedString_Tests.swift */; };
+ C0E1C96C1DD31A0D0068E85C /* NSAttributedString_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C08D04141DC3B16A00575F98 /* NSAttributedString_Tests.swift */; };
+ C0E1C96D1DD31A0D0068E85C /* SwiftyAttributes_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0E211581D9EC5C000623F02 /* SwiftyAttributes_Tests.swift */; };
+ C0E1C96E1DD31A0D0068E85C /* WritingDirection_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0335B631DC0877C009F9B51 /* WritingDirection_Tests.swift */; };
+ C0E1C96F1DD31A0D0068E85C /* Operators_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0335B651DC087A3009F9B51 /* Operators_Tests.swift */; };
+ C0E1C9701DD31A0D0068E85C /* TextEffect_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0D753FA1DC5C77E00BB9754 /* TextEffect_Tests.swift */; };
+ C0E1C99C1DD31C640068E85C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C03658EF1DC84B3F0051F06D /* Images.xcassets */; };
+ C0F001761DDD8EA5009AD8E0 /* SpellingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0F001751DDD8EA5009AD8E0 /* SpellingState.swift */; };
+ C0F96A031DEDE1D300D039A4 /* VerticalGlyphForm_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0F96A021DEDE1D300D039A4 /* VerticalGlyphForm_Tests.swift */; };
+ C0F96A051DEDE23200D039A4 /* String+macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0F96A041DEDE23200D039A4 /* String+macOS.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
- C0E211551D9EC5C000623F02 /* PBXContainerItemProxy */ = {
+ C0782E461DEABEED00E1B99F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C0E211411D9EC5C000623F02 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = C0E211491D9EC5C000623F02;
+ remoteGlobalIDString = C0E1C94A1DD319D50068E85C;
remoteInfo = SwiftyAttributes;
};
+ C0782E481DEABEF100E1B99F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C0E211411D9EC5C000623F02 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C0E1C94A1DD319D50068E85C;
+ remoteInfo = SwiftyAttributes;
+ };
+ C0E1C9551DD319D50068E85C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C0E211411D9EC5C000623F02 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C0E1C94A1DD319D50068E85C;
+ remoteInfo = "SwiftyAttributes-macOS";
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
- C00CF8F21DA6142500B6C1BB /* WritingDirection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WritingDirection.swift; sourceTree = ""; };
- C0127C3B1DB2D5490047DF5A /* Attribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Attribute.swift; sourceTree = ""; };
- C01C438C1DC472F000C49E5E /* TextEffect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextEffect.swift; sourceTree = ""; };
- C0335B5B1DC083A5009F9B51 /* NSAttributedString+SwiftyAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+SwiftyAttributes.swift"; sourceTree = ""; };
- C0335B5D1DC083AE009F9B51 /* String+SwiftyAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+SwiftyAttributes.swift"; sourceTree = ""; };
- C0335B5F1DC08409009F9B51 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; };
- C0335B611DC086B3009F9B51 /* NSMutableAttributedString+SwiftyAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSMutableAttributedString+SwiftyAttributes.swift"; sourceTree = ""; };
+ C027C0C81DEA0A0100953C09 /* SpellingState_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpellingState_Tests.swift; sourceTree = ""; };
+ C027C0CA1DEA452500953C09 /* Attribute+Sequence_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Attribute+Sequence_Tests.swift"; sourceTree = ""; };
C0335B631DC0877C009F9B51 /* WritingDirection_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WritingDirection_Tests.swift; sourceTree = ""; };
C0335B651DC087A3009F9B51 /* Operators_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators_Tests.swift; sourceTree = ""; };
C03658EF1DC84B3F0051F06D /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = SwiftyAttributesTests/Images.xcassets; sourceTree = SOURCE_ROOT; };
@@ -61,17 +83,37 @@
C03659001DC859D80051F06D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
C03659031DC859D80051F06D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
C03659051DC859D80051F06D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- C05C54F61DA61F4E007514C1 /* Ligatures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Ligatures.swift; sourceTree = ""; };
+ C050821E1DFA72F700D39B3B /* Attribute+Sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Attribute+Sequence.swift"; path = "common/Attribute+Sequence.swift"; sourceTree = ""; };
+ C050821F1DFA72F700D39B3B /* Attribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Attribute.swift; path = common/Attribute.swift; sourceTree = ""; };
+ C05082201DFA72F700D39B3B /* AttributeName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AttributeName.swift; path = common/AttributeName.swift; sourceTree = ""; };
+ C05082211DFA72F700D39B3B /* Ligatures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Ligatures.swift; path = common/Ligatures.swift; sourceTree = ""; };
+ C05082221DFA72F700D39B3B /* NSAttributedString+SwiftyAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSAttributedString+SwiftyAttributes.swift"; path = "common/NSAttributedString+SwiftyAttributes.swift"; sourceTree = ""; };
+ C05082231DFA72F700D39B3B /* NSMutableAttributedString+SwiftyAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSMutableAttributedString+SwiftyAttributes.swift"; path = "common/NSMutableAttributedString+SwiftyAttributes.swift"; sourceTree = ""; };
+ C05082241DFA72F700D39B3B /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Operators.swift; path = common/Operators.swift; sourceTree = ""; };
+ C05082251DFA72F700D39B3B /* String+SwiftyAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "String+SwiftyAttributes.swift"; path = "common/String+SwiftyAttributes.swift"; sourceTree = ""; };
+ C05082261DFA72F700D39B3B /* TextEffect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TextEffect.swift; path = common/TextEffect.swift; sourceTree = ""; };
+ C05082271DFA72F700D39B3B /* VerticalGlyphForm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = VerticalGlyphForm.swift; path = common/VerticalGlyphForm.swift; sourceTree = ""; };
+ C05082281DFA72F700D39B3B /* WritingDirection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WritingDirection.swift; path = common/WritingDirection.swift; sourceTree = ""; };
+ C0782E361DEAB30800E1B99F /* ExampleApp-macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-macOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ C0782E381DEAB30800E1B99F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ C0782E3A1DEAB30800E1B99F /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ C0782E3C1DEAB30800E1B99F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ C0782E3F1DEAB30800E1B99F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ C0782E411DEAB30800E1B99F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
C08D04121DC39B5500575F98 /* NSMutableAttributedString_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSMutableAttributedString_Tests.swift; sourceTree = ""; };
C08D04141DC3B16A00575F98 /* NSAttributedString_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSAttributedString_Tests.swift; sourceTree = ""; };
+ C09633DA1DD8016800059332 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ C09633DC1DD8056000059332 /* SwiftyAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwiftyAttributes.h; sourceTree = ""; };
+ C09633DE1DD8057A00059332 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
C0D753FA1DC5C77E00BB9754 /* TextEffect_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextEffect_Tests.swift; sourceTree = ""; };
C0D753FC1DC5C88900BB9754 /* Attribute_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Attribute_Tests.swift; sourceTree = ""; };
- C0E2114A1D9EC5C000623F02 /* SwiftyAttributes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftyAttributes.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- C0E2114D1D9EC5C000623F02 /* SwiftyAttributes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftyAttributes.h; sourceTree = ""; };
- C0E2114E1D9EC5C000623F02 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- C0E211531D9EC5C000623F02 /* SwiftyAttributesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftyAttributesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ C0DB42EB1DDED3500093A6FA /* NSAttributedString+macOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+macOS.swift"; sourceTree = ""; };
+ C0E1C94B1DD319D50068E85C /* SwiftyAttributes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftyAttributes.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ C0E1C9531DD319D50068E85C /* SwiftyAttributesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftyAttributesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
C0E211581D9EC5C000623F02 /* SwiftyAttributes_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftyAttributes_Tests.swift; sourceTree = ""; };
- C0E2115A1D9EC5C000623F02 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ C0F001751DDD8EA5009AD8E0 /* SpellingState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpellingState.swift; sourceTree = ""; };
+ C0F96A021DEDE1D300D039A4 /* VerticalGlyphForm_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticalGlyphForm_Tests.swift; sourceTree = ""; };
+ C0F96A041DEDE23200D039A4 /* String+macOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+macOS.swift"; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -82,18 +124,25 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- C0E211461D9EC5C000623F02 /* Frameworks */ = {
+ C0782E331DEAB30800E1B99F /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ C0E1C9471DD319D50068E85C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
- C0E211501D9EC5C000623F02 /* Frameworks */ = {
+ C0E1C9501DD319D50068E85C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- C0E211541D9EC5C000623F02 /* SwiftyAttributes.framework in Frameworks */,
+ C0E1C9541DD319D50068E85C /* SwiftyAttributes.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -113,12 +162,25 @@
path = "ExampleApp-iOS";
sourceTree = "";
};
+ C0782E371DEAB30800E1B99F /* ExampleApp-macOS */ = {
+ isa = PBXGroup;
+ children = (
+ C0782E381DEAB30800E1B99F /* AppDelegate.swift */,
+ C0782E3A1DEAB30800E1B99F /* ViewController.swift */,
+ C0782E3C1DEAB30800E1B99F /* Assets.xcassets */,
+ C0782E3E1DEAB30800E1B99F /* Main.storyboard */,
+ C0782E411DEAB30800E1B99F /* Info.plist */,
+ );
+ path = "ExampleApp-macOS";
+ sourceTree = "";
+ };
C0E211401D9EC5C000623F02 = {
isa = PBXGroup;
children = (
C0E2114C1D9EC5C000623F02 /* SwiftyAttributes */,
C0E211571D9EC5C000623F02 /* SwiftyAttributesTests */,
C03658F81DC859D80051F06D /* ExampleApp-iOS */,
+ C0782E371DEAB30800E1B99F /* ExampleApp-macOS */,
C0E2114B1D9EC5C000623F02 /* Products */,
);
sourceTree = "";
@@ -126,9 +188,10 @@
C0E2114B1D9EC5C000623F02 /* Products */ = {
isa = PBXGroup;
children = (
- C0E2114A1D9EC5C000623F02 /* SwiftyAttributes.framework */,
- C0E211531D9EC5C000623F02 /* SwiftyAttributesTests.xctest */,
C03658F71DC859D80051F06D /* ExampleApp-iOS.app */,
+ C0E1C94B1DD319D50068E85C /* SwiftyAttributes.framework */,
+ C0E1C9531DD319D50068E85C /* SwiftyAttributesTests.xctest */,
+ C0782E361DEAB30800E1B99F /* ExampleApp-macOS.app */,
);
name = Products;
sourceTree = "";
@@ -136,17 +199,8 @@
C0E2114C1D9EC5C000623F02 /* SwiftyAttributes */ = {
isa = PBXGroup;
children = (
- C0127C3B1DB2D5490047DF5A /* Attribute.swift */,
- C05C54F61DA61F4E007514C1 /* Ligatures.swift */,
- C0335B5F1DC08409009F9B51 /* Operators.swift */,
- C01C438C1DC472F000C49E5E /* TextEffect.swift */,
- C00CF8F21DA6142500B6C1BB /* WritingDirection.swift */,
- C0335B5D1DC083AE009F9B51 /* String+SwiftyAttributes.swift */,
- C0335B5B1DC083A5009F9B51 /* NSAttributedString+SwiftyAttributes.swift */,
- C0335B611DC086B3009F9B51 /* NSMutableAttributedString+SwiftyAttributes.swift */,
- C0E2114D1D9EC5C000623F02 /* SwiftyAttributes.h */,
- C0E2114E1D9EC5C000623F02 /* Info.plist */,
- C03658EF1DC84B3F0051F06D /* Images.xcassets */,
+ C0F001791DDD972D009AD8E0 /* Supporting Files */,
+ C0F001631DDD8E56009AD8E0 /* Sources */,
);
path = SwiftyAttributes;
sourceTree = "";
@@ -155,25 +209,67 @@
isa = PBXGroup;
children = (
C0D753FC1DC5C88900BB9754 /* Attribute_Tests.swift */,
+ C027C0CA1DEA452500953C09 /* Attribute+Sequence_Tests.swift */,
C08D04121DC39B5500575F98 /* NSMutableAttributedString_Tests.swift */,
C08D04141DC3B16A00575F98 /* NSAttributedString_Tests.swift */,
C0E211581D9EC5C000623F02 /* SwiftyAttributes_Tests.swift */,
C0335B631DC0877C009F9B51 /* WritingDirection_Tests.swift */,
C0335B651DC087A3009F9B51 /* Operators_Tests.swift */,
+ C027C0C81DEA0A0100953C09 /* SpellingState_Tests.swift */,
C0D753FA1DC5C77E00BB9754 /* TextEffect_Tests.swift */,
- C0E2115A1D9EC5C000623F02 /* Info.plist */,
+ C09633DA1DD8016800059332 /* Info.plist */,
+ C0F96A021DEDE1D300D039A4 /* VerticalGlyphForm_Tests.swift */,
);
path = SwiftyAttributesTests;
sourceTree = "";
};
+ C0F001631DDD8E56009AD8E0 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ C050821F1DFA72F700D39B3B /* Attribute.swift */,
+ C050821E1DFA72F700D39B3B /* Attribute+Sequence.swift */,
+ C05082201DFA72F700D39B3B /* AttributeName.swift */,
+ C05082211DFA72F700D39B3B /* Ligatures.swift */,
+ C05082221DFA72F700D39B3B /* NSAttributedString+SwiftyAttributes.swift */,
+ C05082231DFA72F700D39B3B /* NSMutableAttributedString+SwiftyAttributes.swift */,
+ C05082241DFA72F700D39B3B /* Operators.swift */,
+ C05082251DFA72F700D39B3B /* String+SwiftyAttributes.swift */,
+ C05082261DFA72F700D39B3B /* TextEffect.swift */,
+ C05082271DFA72F700D39B3B /* VerticalGlyphForm.swift */,
+ C05082281DFA72F700D39B3B /* WritingDirection.swift */,
+ C0F001661DDD8E56009AD8E0 /* macOS */,
+ );
+ path = Sources;
+ sourceTree = "";
+ };
+ C0F001661DDD8E56009AD8E0 /* macOS */ = {
+ isa = PBXGroup;
+ children = (
+ C0F001751DDD8EA5009AD8E0 /* SpellingState.swift */,
+ C0DB42EB1DDED3500093A6FA /* NSAttributedString+macOS.swift */,
+ C0F96A041DEDE23200D039A4 /* String+macOS.swift */,
+ );
+ path = macOS;
+ sourceTree = "";
+ };
+ C0F001791DDD972D009AD8E0 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ C09633DE1DD8057A00059332 /* Info.plist */,
+ C09633DC1DD8056000059332 /* SwiftyAttributes.h */,
+ C03658EF1DC84B3F0051F06D /* Images.xcassets */,
+ );
+ name = "Supporting Files";
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
- C0E211471D9EC5C000623F02 /* Headers */ = {
+ C0E1C9481DD319D50068E85C /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- C0E2115B1D9EC5C000623F02 /* SwiftyAttributes.h in Headers */,
+ C09633E01DD806F600059332 /* SwiftyAttributes.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -191,46 +287,65 @@
buildRules = (
);
dependencies = (
+ C0782E471DEABEED00E1B99F /* PBXTargetDependency */,
);
name = "ExampleApp-iOS";
productName = "ExampleApp-iOS";
productReference = C03658F71DC859D80051F06D /* ExampleApp-iOS.app */;
productType = "com.apple.product-type.application";
};
- C0E211491D9EC5C000623F02 /* SwiftyAttributes */ = {
+ C0782E351DEAB30800E1B99F /* ExampleApp-macOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C0782E441DEAB30800E1B99F /* Build configuration list for PBXNativeTarget "ExampleApp-macOS" */;
+ buildPhases = (
+ C0782E321DEAB30800E1B99F /* Sources */,
+ C0782E331DEAB30800E1B99F /* Frameworks */,
+ C0782E341DEAB30800E1B99F /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ C0782E491DEABEF100E1B99F /* PBXTargetDependency */,
+ );
+ name = "ExampleApp-macOS";
+ productName = "ExampleApp-macOS";
+ productReference = C0782E361DEAB30800E1B99F /* ExampleApp-macOS.app */;
+ productType = "com.apple.product-type.application";
+ };
+ C0E1C94A1DD319D50068E85C /* SwiftyAttributes */ = {
isa = PBXNativeTarget;
- buildConfigurationList = C0E2115E1D9EC5C000623F02 /* Build configuration list for PBXNativeTarget "SwiftyAttributes" */;
+ buildConfigurationList = C0E1C95C1DD319D50068E85C /* Build configuration list for PBXNativeTarget "SwiftyAttributes" */;
buildPhases = (
- C0E211451D9EC5C000623F02 /* Sources */,
- C0E211461D9EC5C000623F02 /* Frameworks */,
- C0E211471D9EC5C000623F02 /* Headers */,
- C0E211481D9EC5C000623F02 /* Resources */,
+ C0E1C9461DD319D50068E85C /* Sources */,
+ C0E1C9471DD319D50068E85C /* Frameworks */,
+ C0E1C9481DD319D50068E85C /* Headers */,
+ C0E1C9491DD319D50068E85C /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = SwiftyAttributes;
- productName = SwiftyAttributes;
- productReference = C0E2114A1D9EC5C000623F02 /* SwiftyAttributes.framework */;
+ productName = "SwiftyAttributes-macOS";
+ productReference = C0E1C94B1DD319D50068E85C /* SwiftyAttributes.framework */;
productType = "com.apple.product-type.framework";
};
- C0E211521D9EC5C000623F02 /* SwiftyAttributesTests */ = {
+ C0E1C9521DD319D50068E85C /* SwiftyAttributesTests */ = {
isa = PBXNativeTarget;
- buildConfigurationList = C0E211611D9EC5C000623F02 /* Build configuration list for PBXNativeTarget "SwiftyAttributesTests" */;
+ buildConfigurationList = C0E1C95F1DD319D50068E85C /* Build configuration list for PBXNativeTarget "SwiftyAttributesTests" */;
buildPhases = (
- C0E2114F1D9EC5C000623F02 /* Sources */,
- C0E211501D9EC5C000623F02 /* Frameworks */,
- C0E211511D9EC5C000623F02 /* Resources */,
+ C0E1C94F1DD319D50068E85C /* Sources */,
+ C0E1C9501DD319D50068E85C /* Frameworks */,
+ C0E1C9511DD319D50068E85C /* Resources */,
);
buildRules = (
);
dependencies = (
- C0E211561D9EC5C000623F02 /* PBXTargetDependency */,
+ C0E1C9561DD319D50068E85C /* PBXTargetDependency */,
);
name = SwiftyAttributesTests;
- productName = SwiftyAttributesTests;
- productReference = C0E211531D9EC5C000623F02 /* SwiftyAttributesTests.xctest */;
+ productName = "SwiftyAttributes-macOSTests";
+ productReference = C0E1C9531DD319D50068E85C /* SwiftyAttributesTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
@@ -239,7 +354,7 @@
C0E211411D9EC5C000623F02 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastSwiftUpdateCheck = 0800;
+ LastSwiftUpdateCheck = 0810;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Eddie Kaiger";
TargetAttributes = {
@@ -248,16 +363,19 @@
DevelopmentTeam = 5KT4ZVPMF8;
ProvisioningStyle = Automatic;
};
- C0E211491D9EC5C000623F02 = {
- CreatedOnToolsVersion = 8.0;
- DevelopmentTeam = 5KT4ZVPMF8;
- LastSwiftMigration = 0800;
+ C0782E351DEAB30800E1B99F = {
+ CreatedOnToolsVersion = 8.1;
ProvisioningStyle = Automatic;
};
- C0E211521D9EC5C000623F02 = {
- CreatedOnToolsVersion = 8.0;
+ C0E1C94A1DD319D50068E85C = {
+ CreatedOnToolsVersion = 8.1;
+ LastSwiftMigration = 0810;
+ ProvisioningStyle = Manual;
+ };
+ C0E1C9521DD319D50068E85C = {
+ CreatedOnToolsVersion = 8.1;
DevelopmentTeam = 5KT4ZVPMF8;
- LastSwiftMigration = 0800;
+ LastSwiftMigration = 0810;
ProvisioningStyle = Automatic;
};
};
@@ -275,9 +393,10 @@
projectDirPath = "";
projectRoot = "";
targets = (
- C0E211491D9EC5C000623F02 /* SwiftyAttributes */,
- C0E211521D9EC5C000623F02 /* SwiftyAttributesTests */,
+ C0E1C94A1DD319D50068E85C /* SwiftyAttributes */,
+ C0E1C9521DD319D50068E85C /* SwiftyAttributesTests */,
C03658F61DC859D80051F06D /* ExampleApp-iOS */,
+ C0782E351DEAB30800E1B99F /* ExampleApp-macOS */,
);
};
/* End PBXProject section */
@@ -294,18 +413,27 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- C0E211481D9EC5C000623F02 /* Resources */ = {
+ C0782E341DEAB30800E1B99F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ C0782E3D1DEAB30800E1B99F /* Assets.xcassets in Resources */,
+ C0782E401DEAB30800E1B99F /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- C0E211511D9EC5C000623F02 /* Resources */ = {
+ C0E1C9491DD319D50068E85C /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- C03658F21DC84CCA0051F06D /* Images.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ C0E1C9511DD319D50068E85C /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C0E1C99C1DD31C640068E85C /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -321,42 +449,70 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- C0E211451D9EC5C000623F02 /* Sources */ = {
+ C0782E321DEAB30800E1B99F /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C0782E3B1DEAB30800E1B99F /* ViewController.swift in Sources */,
+ C0782E391DEAB30800E1B99F /* AppDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ C0E1C9461DD319D50068E85C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- C0335B5C1DC083A5009F9B51 /* NSAttributedString+SwiftyAttributes.swift in Sources */,
- C00CF8F31DA6142500B6C1BB /* WritingDirection.swift in Sources */,
- C0335B601DC08409009F9B51 /* Operators.swift in Sources */,
- C05C54F71DA61F4E007514C1 /* Ligatures.swift in Sources */,
- C0127C3C1DB2D5490047DF5A /* Attribute.swift in Sources */,
- C01C438D1DC472F000C49E5E /* TextEffect.swift in Sources */,
- C0335B5E1DC083AE009F9B51 /* String+SwiftyAttributes.swift in Sources */,
- C0335B621DC086B3009F9B51 /* NSMutableAttributedString+SwiftyAttributes.swift in Sources */,
+ C050822A1DFA72F700D39B3B /* Attribute.swift in Sources */,
+ C050822F1DFA72F700D39B3B /* Operators.swift in Sources */,
+ C050822E1DFA72F700D39B3B /* NSMutableAttributedString+SwiftyAttributes.swift in Sources */,
+ C050822B1DFA72F700D39B3B /* AttributeName.swift in Sources */,
+ C05082331DFA72F700D39B3B /* WritingDirection.swift in Sources */,
+ C050822C1DFA72F700D39B3B /* Ligatures.swift in Sources */,
+ C05082311DFA72F700D39B3B /* TextEffect.swift in Sources */,
+ C05082301DFA72F700D39B3B /* String+SwiftyAttributes.swift in Sources */,
+ C0DB42EC1DDED3500093A6FA /* NSAttributedString+macOS.swift in Sources */,
+ C05082321DFA72F700D39B3B /* VerticalGlyphForm.swift in Sources */,
+ C050822D1DFA72F700D39B3B /* NSAttributedString+SwiftyAttributes.swift in Sources */,
+ C0F96A051DEDE23200D039A4 /* String+macOS.swift in Sources */,
+ C0F001761DDD8EA5009AD8E0 /* SpellingState.swift in Sources */,
+ C05082291DFA72F700D39B3B /* Attribute+Sequence.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- C0E2114F1D9EC5C000623F02 /* Sources */ = {
+ C0E1C94F1DD319D50068E85C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- C0335B641DC0877C009F9B51 /* WritingDirection_Tests.swift in Sources */,
- C0D753FB1DC5C77E00BB9754 /* TextEffect_Tests.swift in Sources */,
- C08D04131DC39B5500575F98 /* NSMutableAttributedString_Tests.swift in Sources */,
- C0D753FD1DC5C88900BB9754 /* Attribute_Tests.swift in Sources */,
- C0E211591D9EC5C000623F02 /* SwiftyAttributes_Tests.swift in Sources */,
- C0335B661DC087A3009F9B51 /* Operators_Tests.swift in Sources */,
- C08D04151DC3B16A00575F98 /* NSAttributedString_Tests.swift in Sources */,
+ C0E1C96E1DD31A0D0068E85C /* WritingDirection_Tests.swift in Sources */,
+ C0E1C96B1DD31A0D0068E85C /* NSMutableAttributedString_Tests.swift in Sources */,
+ C0E1C96D1DD31A0D0068E85C /* SwiftyAttributes_Tests.swift in Sources */,
+ C0E1C96A1DD31A0D0068E85C /* Attribute_Tests.swift in Sources */,
+ C0E1C9701DD31A0D0068E85C /* TextEffect_Tests.swift in Sources */,
+ C027C0C91DEA0A0100953C09 /* SpellingState_Tests.swift in Sources */,
+ C0F96A031DEDE1D300D039A4 /* VerticalGlyphForm_Tests.swift in Sources */,
+ C027C0CB1DEA452500953C09 /* Attribute+Sequence_Tests.swift in Sources */,
+ C0E1C96F1DD31A0D0068E85C /* Operators_Tests.swift in Sources */,
+ C0E1C96C1DD31A0D0068E85C /* NSAttributedString_Tests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
- C0E211561D9EC5C000623F02 /* PBXTargetDependency */ = {
+ C0782E471DEABEED00E1B99F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C0E1C94A1DD319D50068E85C /* SwiftyAttributes */;
+ targetProxy = C0782E461DEABEED00E1B99F /* PBXContainerItemProxy */;
+ };
+ C0782E491DEABEF100E1B99F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = C0E211491D9EC5C000623F02 /* SwiftyAttributes */;
- targetProxy = C0E211551D9EC5C000623F02 /* PBXContainerItemProxy */;
+ target = C0E1C94A1DD319D50068E85C /* SwiftyAttributes */;
+ targetProxy = C0782E481DEABEF100E1B99F /* PBXContainerItemProxy */;
+ };
+ C0E1C9561DD319D50068E85C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C0E1C94A1DD319D50068E85C /* SwiftyAttributes */;
+ targetProxy = C0E1C9551DD319D50068E85C /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
@@ -377,6 +533,14 @@
name = LaunchScreen.storyboard;
sourceTree = "";
};
+ C0782E3E1DEAB30800E1B99F /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ C0782E3F1DEAB30800E1B99F /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
@@ -384,13 +548,18 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEVELOPMENT_TEAM = 5KT4ZVPMF8;
INFOPLIST_FILE = "ExampleApp-iOS/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.eddiekaiger.ExampleApp-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_VERSION = 3.0.1;
+ TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
@@ -398,13 +567,118 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEVELOPMENT_TEAM = 5KT4ZVPMF8;
INFOPLIST_FILE = "ExampleApp-iOS/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.eddiekaiger.ExampleApp-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_VERSION = 3.0.1;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ C0782E421DEAB30800E1B99F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "-";
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = "ExampleApp-macOS/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.eddiekaiger.ExampleApp-macOS";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ C0782E431DEAB30800E1B99F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "-";
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = "ExampleApp-macOS/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.eddiekaiger.ExampleApp-macOS";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SWIFT_VERSION = 3.0;
+ };
+ name = Release;
+ };
+ C0E1C95D1DD319D50068E85C /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = "";
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ FRAMEWORK_VERSION = A;
+ INFOPLIST_FILE = SwiftyAttributes/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.eddiekaiger.SwiftyAttributes;
+ PRODUCT_BUNDLE_PACKAGE_TYPE = FMWK;
+ PRODUCT_NAME = SwiftyAttributes;
+ SKIP_INSTALL = YES;
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ C0E1C95E1DD319D50068E85C /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = "";
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ FRAMEWORK_VERSION = A;
+ INFOPLIST_FILE = SwiftyAttributes/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.eddiekaiger.SwiftyAttributes;
+ PRODUCT_BUNDLE_PACKAGE_TYPE = FMWK;
+ PRODUCT_NAME = SwiftyAttributes;
+ SKIP_INSTALL = YES;
+ SWIFT_VERSION = 3.0;
+ };
+ name = Release;
+ };
+ C0E1C9601DD319D50068E85C /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = SwiftyAttributes/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks @loader_path/Frameworks @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.eddiekaiger.SwiftyAttributesTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ C0E1C9611DD319D50068E85C /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = SwiftyAttributes/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks @loader_path/Frameworks @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.eddiekaiger.SwiftyAttributesTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -430,7 +704,6 @@
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
@@ -451,14 +724,18 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
- SDKROOT = iphoneos;
+ PRODUCT_BUNDLE_PACKAGE_TYPE = BNDL;
+ SUPPORTED_PLATFORMS = "watchsimulator watchos appletvos appletvsimulator iphoneos iphonesimulator macosx";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = "1,2,3,4";
+ TVOS_DEPLOYMENT_TARGET = 9.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
+ WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
name = Debug;
};
@@ -484,7 +761,6 @@
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@@ -499,80 +775,17 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
- SDKROOT = iphoneos;
+ PRODUCT_BUNDLE_PACKAGE_TYPE = BNDL;
+ SUPPORTED_PLATFORMS = "watchsimulator watchos appletvos appletvsimulator iphoneos iphonesimulator macosx";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = "1,2,3,4";
+ TVOS_DEPLOYMENT_TARGET = 9.0;
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
- };
- name = Release;
- };
- C0E2115F1D9EC5C000623F02 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_ENABLE_MODULES = YES;
- CODE_SIGN_IDENTITY = "";
- DEFINES_MODULE = YES;
- DEVELOPMENT_TEAM = 5KT4ZVPMF8;
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
- DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = SwiftyAttributes/Info.plist;
- INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.eddiekaiger.SwiftyAttributes;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SKIP_INSTALL = YES;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 3.0;
- };
- name = Debug;
- };
- C0E211601D9EC5C000623F02 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_ENABLE_MODULES = YES;
- CODE_SIGN_IDENTITY = "";
- DEFINES_MODULE = YES;
- DEVELOPMENT_TEAM = 5KT4ZVPMF8;
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
- DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = SwiftyAttributes/Info.plist;
- INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.eddiekaiger.SwiftyAttributes;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SKIP_INSTALL = YES;
- SWIFT_VERSION = 3.0;
- };
- name = Release;
- };
- C0E211621D9EC5C000623F02 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
- DEVELOPMENT_TEAM = 5KT4ZVPMF8;
- INFOPLIST_FILE = SwiftyAttributesTests/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.eddiekaiger.SwiftyAttributesTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
- };
- name = Debug;
- };
- C0E211631D9EC5C000623F02 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
- DEVELOPMENT_TEAM = 5KT4ZVPMF8;
- INFOPLIST_FILE = SwiftyAttributesTests/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.eddiekaiger.SwiftyAttributesTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
name = Release;
};
@@ -588,29 +801,38 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- C0E211441D9EC5C000623F02 /* Build configuration list for PBXProject "SwiftyAttributes" */ = {
+ C0782E441DEAB30800E1B99F /* Build configuration list for PBXNativeTarget "ExampleApp-macOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- C0E2115C1D9EC5C000623F02 /* Debug */,
- C0E2115D1D9EC5C000623F02 /* Release */,
+ C0782E421DEAB30800E1B99F /* Debug */,
+ C0782E431DEAB30800E1B99F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C0E1C95C1DD319D50068E85C /* Build configuration list for PBXNativeTarget "SwiftyAttributes" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C0E1C95D1DD319D50068E85C /* Debug */,
+ C0E1C95E1DD319D50068E85C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- C0E2115E1D9EC5C000623F02 /* Build configuration list for PBXNativeTarget "SwiftyAttributes" */ = {
+ C0E1C95F1DD319D50068E85C /* Build configuration list for PBXNativeTarget "SwiftyAttributesTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- C0E2115F1D9EC5C000623F02 /* Debug */,
- C0E211601D9EC5C000623F02 /* Release */,
+ C0E1C9601DD319D50068E85C /* Debug */,
+ C0E1C9611DD319D50068E85C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- C0E211611D9EC5C000623F02 /* Build configuration list for PBXNativeTarget "SwiftyAttributesTests" */ = {
+ C0E211441D9EC5C000623F02 /* Build configuration list for PBXProject "SwiftyAttributes" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- C0E211621D9EC5C000623F02 /* Debug */,
- C0E211631D9EC5C000623F02 /* Release */,
+ C0E2115C1D9EC5C000623F02 /* Debug */,
+ C0E2115D1D9EC5C000623F02 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
diff --git a/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/ExampleApp-iOS.xcscheme b/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/ExampleApp-iOS.xcscheme
new file mode 100644
index 0000000..5e6acd5
--- /dev/null
+++ b/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/ExampleApp-iOS.xcscheme
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/ExampleApp-macOS.xcscheme b/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/ExampleApp-macOS.xcscheme
new file mode 100644
index 0000000..d827b7a
--- /dev/null
+++ b/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/ExampleApp-macOS.xcscheme
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/SwiftyAttributes.xcscheme b/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/SwiftyAttributes.xcscheme
index b561349..c19013a 100644
--- a/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/SwiftyAttributes.xcscheme
+++ b/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/SwiftyAttributes.xcscheme
@@ -1,6 +1,6 @@
@@ -26,13 +26,14 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES">
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ codeCoverageEnabled = "YES">
@@ -42,7 +43,7 @@
@@ -64,7 +65,7 @@
@@ -82,7 +83,7 @@
diff --git a/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/SwiftyAttributesTests.xcscheme b/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/SwiftyAttributesTests.xcscheme
index 383e480..c8d6359 100644
--- a/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/SwiftyAttributesTests.xcscheme
+++ b/SwiftyAttributes.xcodeproj/xcshareddata/xcschemes/SwiftyAttributesTests.xcscheme
@@ -1,7 +1,7 @@
+ LastUpgradeVersion = "0810"
+ version = "1.7">
@@ -10,18 +10,21 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES"
- codeCoverageEnabled = "YES">
+ shouldUseLaunchSchemeArgsEnv = "YES">
+
+
diff --git a/SwiftyAttributes/Attribute.swift b/SwiftyAttributes/Attribute.swift
deleted file mode 100644
index 1cefbb9..0000000
--- a/SwiftyAttributes/Attribute.swift
+++ /dev/null
@@ -1,250 +0,0 @@
-//
-// Attribute.swift
-// SwiftyAttributes
-//
-// Created by Eddie Kaiger on 10/15/16.
-// Copyright © 2016 Eddie Kaiger. All rights reserved.
-//
-
-import Foundation
-
-public typealias UnderlineStyle = NSUnderlineStyle
-public typealias StrikethroughStyle = NSUnderlineStyle
-
-/**
- Represents attributes that can be applied to NSAttributedStrings.
- */
-public enum Attribute {
-
- /// Attachment attribute that allows items like images to be inserted into text.
- case attachment(NSTextAttachment)
-
- /// Value indicating the character's offset from the baseline, in points.
- case baselineOffset(Double)
-
- /// The background color of the attributed string.
- case backgroundColor(UIColor)
-
- /// Value indicating the log of the expansion factor to be applied to glyphs.
- case expansion(Double)
-
- /// The font of the attributed string.
- case font(UIFont)
-
- /// Specifies the number of points by which to adjust kern-pair characters. Kerning prevents unwanted space from occurring between specific characters and depends on the font. The value 0 means kerning is disabled (default).
- case kern(Double)
-
- /// Ligatures cause specific character combinations to be rendered using a single custom glyph that corresponds to those characters. See `Ligatures` for values.
- case ligatures(Ligatures)
-
- /// A URL link to attach to the attributed string.
- case link(URL)
-
- /// A value indicating the skew to be applied to glyphs.
- case obliqueness(Double)
-
- /// An `NSParagraphStyle` to be applied to the attributed string.
- case paragraphStyle(NSParagraphStyle)
-
- /// A shadow to be applied to the characters.
- case shadow(NSShadow)
-
- /// The color of the stroke (border) around the characters.
- case strokeColor(UIColor)
-
- /// The width/thickness of the stroke (border) around the characters.
- case strokeWidth(Double)
-
- /// The color of the strikethrough.
- case strikethroughColor(UIColor)
-
- /// The style of the strikethrough.
- case strikethroughStyle(StrikethroughStyle)
-
- /// The text color.
- case textColor(UIColor)
-
- /// The text effect to apply. See `TextEffect` for possible values.
- case textEffect(TextEffect)
-
- /// The color of the underline.
- case underlineColor(UIColor)
-
- /// The style of the underline.
- case underlineStyle(UnderlineStyle)
-
- /// The writing directions to apply to the attributed string. See `WritingDirection` for values. Only available on iOS 9.0+.
- case writingDirections([WritingDirection])
-
- init(name: Attribute.Name, value: Any) {
- func validate(_ val: Any) -> Type {
- return val as! Type
- }
-
- switch name {
- case .attachment: self = .attachment(validate(value))
- case .baselineOffset: self = .baselineOffset(validate(value))
- case .backgroundColor: self = .backgroundColor(validate(value))
- case .expansion: self = .expansion(validate(value))
- case .font: self = .font(validate(value))
- case .kern: self = .kern(validate(value))
- case .ligature: self = .ligatures(validate(value))
- case .link: self = .link(validate(value))
- case .obliqueness: self = .obliqueness(validate(value))
- case .paragraphStyle: self = .paragraphStyle(validate(value))
- case .shadow: self = .shadow(validate(value))
- case .strokeColor: self = .strokeColor(validate(value))
- case .strokeWidth: self = .strokeWidth(validate(value))
- case .strikethroughColor: self = .strikethroughColor(validate(value))
- case .strikethroughStyle: self = .strikethroughStyle(validate(value))
- case .textColor: self = .textColor(validate(value))
- case .textEffect: self = .textEffect(validate(value))
- case .underlineColor: self = .underlineColor(validate(value))
- case .underlineStyle: self = .underlineStyle(validate(value))
- case .writingDirection: self = .writingDirections(validate(value))
- }
- }
-
- /// The key name corresponding to the attribute.
- public var keyName: String {
- let name: Attribute.Name
- switch self {
- case .attachment(_): name = .attachment
- case .baselineOffset(_): name = .baselineOffset
- case .backgroundColor(_): name = .backgroundColor
- case .expansion(_): name = .expansion
- case .font(_): name = .font
- case .kern(_): name = .kern
- case .ligatures(_): name = .ligature
- case .link(_): name = .link
- case .obliqueness(_): name = .obliqueness
- case .paragraphStyle(_): name = .paragraphStyle
- case .shadow(_): name = .shadow
- case .strokeColor(_): name = .strokeColor
- case .strokeWidth(_): name = .strokeWidth
- case .strikethroughColor(_): name = .strikethroughColor
- case .strikethroughStyle(_): name = .strikethroughStyle
- case .textColor(_): name = .textColor
- case .textEffect(_): name = .textEffect
- case .underlineColor(_): name = .underlineColor
- case .underlineStyle(_): name = .underlineStyle
- case .writingDirections(_): name = .writingDirection
- }
- return name.rawValue
- }
-
- // Convenience getter variable for the associated value of the attribute. See each case to determine the return type.
- public var value: Any {
- switch self {
- case .attachment(let attachment): return attachment
- case .baselineOffset(let offset): return offset
- case .backgroundColor(let color): return color
- case .expansion(let expansion): return expansion
- case .font(let font): return font
- case .kern(let kern): return kern
- case .ligatures(let ligatures): return ligatures
- case .link(let link): return link
- case .obliqueness(let value): return value
- case .paragraphStyle(let style): return style
- case .shadow(let shadow): return shadow
- case .strokeColor(let color): return color
- case .strokeWidth(let width): return width
- case .strikethroughColor(let color): return color
- case .strikethroughStyle(let style): return style
- case .textColor(let color): return color
- case .textEffect(let effect): return effect
- case .underlineColor(let color): return color
- case .underlineStyle(let style): return style
- case .writingDirections(let directions): return directions
- }
- }
-
- var foundationValue: Any {
- switch self {
- case .ligatures(let ligatures): return ligatures.rawValue
- case .strikethroughStyle(let style): return NSNumber(value: style.rawValue)
- case .textEffect(let effect): return effect.rawValue
- case .underlineStyle(let style): return NSNumber(value: style.rawValue)
- case .writingDirections(let directions): return directions.map { $0.rawValue }
- default: return value
- }
- }
-
- /**
- An enum that corresponds to `Attribute`, mapping attributes to their respective names.
- */
- public enum Name: RawRepresentable {
- case attachment
- case baselineOffset
- case backgroundColor
- case expansion
- case font
- case kern
- case ligature
- case link
- case obliqueness
- case paragraphStyle
- case shadow
- case strokeColor
- case strokeWidth
- case strikethroughColor
- case strikethroughStyle
- case textColor
- case textEffect
- case underlineColor
- case underlineStyle
- case writingDirection
-
- public init?(rawValue: String) {
- switch rawValue {
- case NSAttachmentAttributeName: self = .attachment
- case NSBaselineOffsetAttributeName: self = .baselineOffset
- case NSBackgroundColorAttributeName: self = .backgroundColor
- case NSExpansionAttributeName: self = .expansion
- case NSFontAttributeName: self = .font
- case NSKernAttributeName: self = .kern
- case NSLigatureAttributeName: self = .ligature
- case NSLinkAttributeName: self = .link
- case NSObliquenessAttributeName: self = .obliqueness
- case NSParagraphStyleAttributeName: self = .paragraphStyle
- case NSShadowAttributeName: self = .shadow
- case NSStrokeColorAttributeName: self = .strokeColor
- case NSStrokeWidthAttributeName: self = .strokeWidth
- case NSStrikethroughColorAttributeName: self = .strikethroughColor
- case NSStrikethroughStyleAttributeName: self = .strikethroughStyle
- case NSForegroundColorAttributeName: self = .textColor
- case NSTextEffectAttributeName: self = .textEffect
- case NSUnderlineColorAttributeName: self = .underlineColor
- case NSUnderlineStyleAttributeName: self = .underlineStyle
- case NSWritingDirectionAttributeName: self = .writingDirection
- default: return nil
- }
- }
-
- public var rawValue: String {
- switch self {
- case .attachment: return NSAttachmentAttributeName
- case .baselineOffset: return NSBaselineOffsetAttributeName
- case .backgroundColor: return NSBackgroundColorAttributeName
- case .expansion: return NSExpansionAttributeName
- case .font: return NSFontAttributeName
- case .kern: return NSKernAttributeName
- case .ligature: return NSLigatureAttributeName
- case .link: return NSLinkAttributeName
- case .obliqueness: return NSObliquenessAttributeName
- case .paragraphStyle: return NSParagraphStyleAttributeName
- case .shadow: return NSShadowAttributeName
- case .strokeColor: return NSStrokeColorAttributeName
- case .strokeWidth: return NSStrokeWidthAttributeName
- case .strikethroughColor: return NSStrikethroughColorAttributeName
- case .strikethroughStyle: return NSStrikethroughStyleAttributeName
- case .textColor: return NSForegroundColorAttributeName
- case .textEffect: return NSTextEffectAttributeName
- case .underlineColor: return NSUnderlineColorAttributeName
- case .underlineStyle: return NSUnderlineStyleAttributeName
- case .writingDirection: return NSWritingDirectionAttributeName
- }
-
- }
- }
-}
diff --git a/SwiftyAttributes/Info.plist b/SwiftyAttributes/Info.plist
index ee73227..d0cdb4b 100644
--- a/SwiftyAttributes/Info.plist
+++ b/SwiftyAttributes/Info.plist
@@ -13,12 +13,14 @@
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
- FMWK
+ BNDL
CFBundleShortVersionString
- 3.0.0
+ 3.1.0
+ CFBundleSignature
+ ????
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
- NSPrincipalClass
-
+ NSHumanReadableCopyright
+ Copyright © 2016 Eddie Kaiger. All rights reserved.
diff --git a/SwiftyAttributes/Sources/common/Attribute+Sequence.swift b/SwiftyAttributes/Sources/common/Attribute+Sequence.swift
new file mode 100644
index 0000000..c8d12ba
--- /dev/null
+++ b/SwiftyAttributes/Sources/common/Attribute+Sequence.swift
@@ -0,0 +1,41 @@
+//
+// AttributeConversions.swift
+// SwiftyAttributes
+//
+// Created by Eddie Kaiger on 11/23/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+/**
+ An extension on dictionaries that allows us to convert a Foundation-based dictionary of attributes to an array of `Attribute`s.
+
+ A Sequence with an iterator of (String, Any) is equivalent to [String: Any]
+ This is a simple syntactic workaround since we can't write "extension Dictionary where Key == String". Thanks Swift :)
+ */
+extension Sequence where Iterator.Element == (key: String, value: Any) {
+
+ /// Returns an array of `Attribute`s converted from the dictionary of attributes. Use this whenever you want to convert [String: Any] to [Attribute].
+ public var swiftyAttributes: [Attribute] {
+ return flatMap { name, value in
+ if let attrName = Attribute.Name(rawValue: name) {
+ return Attribute(name: attrName, foundationValue: value)
+ } else {
+ return nil
+ }
+ }
+ }
+
+}
+
+extension Sequence where Iterator.Element == Attribute {
+
+ /// Returns the attribute dictionary required by Foundation's API for attributed strings. Use this whenever you need to convert [Attribute] to [String: Any].
+ public var foundationAttributes: [String: Any] {
+ return reduce([String: Any]()) { dictionary, attribute in
+ var dict = dictionary
+ dict[attribute.keyName] = attribute.foundationValue
+ return dict
+ }
+ }
+
+}
diff --git a/SwiftyAttributes/Sources/common/Attribute.swift b/SwiftyAttributes/Sources/common/Attribute.swift
new file mode 100644
index 0000000..3149dd1
--- /dev/null
+++ b/SwiftyAttributes/Sources/common/Attribute.swift
@@ -0,0 +1,330 @@
+//
+// Attribute.swift
+// SwiftyAttributes
+//
+// Created by Eddie Kaiger on 10/15/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+#if os(macOS)
+ import AppKit
+ public typealias Color = NSColor
+ public typealias Font = NSFont
+ public typealias Cursor = NSCursor
+ public typealias TextAlternatives = NSTextAlternatives
+#else
+ import UIKit
+ public typealias Color = UIColor
+ public typealias Font = UIFont
+#endif
+
+public typealias UnderlineStyle = NSUnderlineStyle
+public typealias StrikethroughStyle = NSUnderlineStyle
+public typealias ParagraphStyle = NSParagraphStyle
+
+#if os(watchOS)
+#else
+public typealias Shadow = NSShadow
+public typealias TextAttachment = NSTextAttachment
+#endif
+
+/**
+ Represents attributes that can be applied to NSAttributedStrings.
+ */
+public enum Attribute {
+
+ #if os(watchOS)
+ #else
+ /// Attachment attribute that allows items like images to be inserted into text.
+ case attachment(TextAttachment)
+ #endif
+
+ /// Value indicating the character's offset from the baseline, in points.
+ case baselineOffset(Double)
+
+ /// The background color of the attributed string.
+ case backgroundColor(Color)
+
+ #if os(macOS)
+ /// The cursor object associated with the attributed string.
+ case cursor(Cursor)
+ #endif
+
+ /// Value indicating the log of the expansion factor to be applied to glyphs.
+ case expansion(Double)
+
+ /// The font of the attributed string.
+ case font(Font)
+
+ /// Specifies the number of points by which to adjust kern-pair characters. Kerning prevents unwanted space from occurring between specific characters and depends on the font. The value 0 means kerning is disabled (default).
+ case kern(Double)
+
+ /// Ligatures cause specific character combinations to be rendered using a single custom glyph that corresponds to those characters. See `Ligatures` for values.
+ case ligatures(Ligatures)
+
+ /// A URL link to attach to the attributed string.
+ case link(URL)
+
+ #if os(macOS)
+ /// The index in marked text indicating clause segments.
+ case markedClauseSegment(Int)
+ #endif
+
+ /// A value indicating the skew to be applied to glyphs.
+ case obliqueness(Double)
+
+ /// An `NSParagraphStyle` to be applied to the attributed string.
+ case paragraphStyle(ParagraphStyle)
+
+ #if os(watchOS)
+ #else
+ /// A shadow to be applied to the characters.
+ case shadow(Shadow)
+ #endif
+
+ #if os(macOS)
+ /// A state indicating a spelling or grammar error. See `SpellingState` for possible values.
+ case spellingState(SpellingState)
+ #endif
+
+ /// The color of the stroke (border) around the characters.
+ case strokeColor(Color)
+
+ /// The width/thickness of the stroke (border) around the characters.
+ case strokeWidth(Double)
+
+ /// The color of the strikethrough.
+ case strikethroughColor(Color)
+
+ /// The style of the strikethrough.
+ case strikethroughStyle(StrikethroughStyle)
+
+ #if os(macOS)
+ /// The superscript attribute.
+ case superscript(Int)
+
+ /// The object representing alternatives for a string that may be presented to the user.
+ case textAlternatives(TextAlternatives)
+ #endif
+
+ /// The text color.
+ case textColor(Color)
+
+ /// The text effect to apply. See `TextEffect` for possible values.
+ case textEffect(TextEffect)
+
+ #if os(macOS)
+ /// The text of the tooltip.
+ case toolTip(String)
+ #endif
+
+ /// The color of the underline.
+ case underlineColor(Color)
+
+ /// The style of the underline.
+ case underlineStyle(UnderlineStyle)
+
+ /// The vertical glyph form (horizontal or vertical text). See `VerticalGlyphForm` for details.
+ case verticalGlyphForm(VerticalGlyphForm)
+
+ /// The writing directions to apply to the attributed string. See `WritingDirection` for values. Only available on iOS 9.0+.
+ case writingDirections([WritingDirection])
+
+ init(name: Attribute.Name, foundationValue: Any) {
+ func validate(_ val: Any) -> Type {
+ assert(val is Type, "Attribute with name \(name.rawValue) must have a value of type \(Type.self)")
+ return val as! Type
+ }
+
+ func validateDouble(_ val: Any) -> Double {
+ assert(val is NSNumber, "Attribute with name \(name.rawValue) must have a value that is castable to NSNumber")
+ return (val as! NSNumber).doubleValue
+ }
+
+ var ret: Attribute!
+
+ // Bug in Swift prevents us from putting directives inside switch statements (https://bugs.swift.org/browse/SR-2)
+
+ #if os(watchOS)
+ #else
+ switch name {
+ case .attachment: ret = .attachment(validate(foundationValue))
+ case .shadow: ret = .shadow(validate(foundationValue))
+ default: break
+ }
+ #endif
+
+ #if os(macOS)
+ switch name {
+ case .cursor: ret = .cursor(validate(foundationValue))
+ case .markedClauseSegment: ret = .markedClauseSegment(validate(foundationValue))
+ case .spellingState: ret = .spellingState(SpellingState(rawValue: validate(foundationValue))!)
+ case .superscript: ret = .superscript(validate(foundationValue))
+ case .textAlternatives: ret = .textAlternatives(validate(foundationValue))
+ case .toolTip: ret = .toolTip(validate(foundationValue))
+ default: break
+ }
+ #endif
+
+ switch name {
+ case .baselineOffset: ret = .baselineOffset(validateDouble(foundationValue))
+ case .backgroundColor: ret = .backgroundColor(validate(foundationValue))
+ case .expansion: ret = .expansion(validateDouble(foundationValue))
+ case .font: ret = .font(validate(foundationValue))
+ case .kern: ret = .kern(validateDouble(foundationValue))
+ case .ligature: ret = .ligatures(Ligatures(rawValue: validate(foundationValue))!)
+ case .link: ret = .link(validate(foundationValue))
+ case .obliqueness: ret = .obliqueness(validateDouble(foundationValue))
+ case .paragraphStyle: ret = .paragraphStyle(validate(foundationValue))
+ case .strokeColor: ret = .strokeColor(validate(foundationValue))
+ case .strokeWidth: ret = .strokeWidth(validateDouble(foundationValue))
+ case .strikethroughColor: ret = .strikethroughColor(validate(foundationValue))
+ case .strikethroughStyle: ret = .strikethroughStyle(StrikethroughStyle(rawValue: validate(foundationValue))!)
+ case .textColor: ret = .textColor(validate(foundationValue))
+ case .textEffect: ret = .textEffect(TextEffect(rawValue: validate(foundationValue))!)
+ case .underlineColor: ret = .underlineColor(validate(foundationValue))
+ case .underlineStyle: ret = .underlineStyle(UnderlineStyle(rawValue: validate(foundationValue))!)
+ case .verticalGlyphForm: ret = .verticalGlyphForm(VerticalGlyphForm(rawValue: validate(foundationValue))!)
+ case .writingDirection:
+ let values: [Int] = validate(foundationValue)
+ ret = .writingDirections(values.flatMap(WritingDirection.init))
+ default: break
+ }
+
+ self = ret
+ }
+
+ /// The key name corresponding to the attribute.
+ public var keyName: String {
+
+ var name: Attribute.Name!
+
+ // Bug in Swift prevents us from putting directives inside switch statements (https://bugs.swift.org/browse/SR-2)
+
+ #if os(watchOS)
+ #else
+ switch self {
+ case .attachment(_): name = .attachment
+ case .shadow(_): name = .shadow
+ default: break
+ }
+ #endif
+
+ #if os(macOS)
+ switch self {
+ case .cursor(_): name = .cursor
+ case .markedClauseSegment(_): name = .markedClauseSegment
+ case .spellingState(_): name = .spellingState
+ case .superscript(_): name = .superscript
+ case .textAlternatives(_): name = .textAlternatives
+ case .toolTip(_): name = .toolTip
+ default: break
+ }
+ #endif
+
+ switch self {
+ case .baselineOffset(_): name = .baselineOffset
+ case .backgroundColor(_): name = .backgroundColor
+ case .expansion(_): name = .expansion
+ case .font(_): name = .font
+ case .kern(_): name = .kern
+ case .ligatures(_): name = .ligature
+ case .link(_): name = .link
+ case .obliqueness(_): name = .obliqueness
+ case .paragraphStyle(_): name = .paragraphStyle
+ case .strokeColor(_): name = .strokeColor
+ case .strokeWidth(_): name = .strokeWidth
+ case .strikethroughColor(_): name = .strikethroughColor
+ case .strikethroughStyle(_): name = .strikethroughStyle
+ case .textColor(_): name = .textColor
+ case .textEffect(_): name = .textEffect
+ case .underlineColor(_): name = .underlineColor
+ case .underlineStyle(_): name = .underlineStyle
+ case .writingDirections(_): name = .writingDirection
+ case .verticalGlyphForm(_): name = .verticalGlyphForm
+ default: break
+ }
+
+ return name.rawValue
+ }
+
+ // Convenience getter variable for the associated value of the attribute. See each case to determine the return type.
+ public var value: Any {
+
+ var ret: Any!
+
+ // Bug in Swift prevents us from putting directives inside switch statements (https://bugs.swift.org/browse/SR-2)
+
+ #if os(watchOS)
+ #else
+ switch self {
+ case .attachment(let attachment): ret = attachment
+ case .shadow(let shadow): ret = shadow
+ default: break
+ }
+ #endif
+
+ #if os(macOS)
+ switch self {
+ case .cursor(let cursor): ret = cursor
+ case .markedClauseSegment(let segment): ret = segment
+ case .spellingState(let state): ret = state
+ case .superscript(let superscript): ret = superscript
+ case .textAlternatives(let alternatives): ret = alternatives
+ case .toolTip(let text): ret = text
+ default: break
+ }
+ #endif
+
+ switch self {
+ case .baselineOffset(let offset): ret = offset
+ case .backgroundColor(let color): ret = color
+ case .expansion(let expansion): ret = expansion
+ case .font(let font): ret = font
+ case .kern(let kern): ret = kern
+ case .ligatures(let ligatures): ret = ligatures
+ case .link(let link): ret = link
+ case .obliqueness(let value): ret = value
+ case .paragraphStyle(let style): ret = style
+ case .strokeColor(let color): ret = color
+ case .strokeWidth(let width): ret = width
+ case .strikethroughColor(let color): ret = color
+ case .strikethroughStyle(let style): ret = style
+ case .textColor(let color): ret = color
+ case .textEffect(let effect): ret = effect
+ case .underlineColor(let color): ret = color
+ case .underlineStyle(let style): ret = style
+ case .verticalGlyphForm(let form): ret = form
+ case .writingDirections(let directions): ret = directions
+ default: break
+ }
+
+ return ret
+ }
+
+ /// The value that is passed into the original attribute dictionary of Foundation's API for NSAttributedStrings. Consists of basic types such as Int, Color, Font, etc.
+ public var foundationValue: Any {
+ #if os(macOS)
+ switch self {
+ case .spellingState(let state): return state.rawValue
+ default: break
+ }
+ #endif
+
+ switch self {
+ case .ligatures(let ligatures): return ligatures.rawValue
+ case .strikethroughStyle(let style): return style.rawValue
+ case .textEffect(let effect): return effect.rawValue
+ case .underlineStyle(let style): return style.rawValue
+ case .writingDirections(let directions): return directions.map { $0.rawValue }
+ case .verticalGlyphForm(let form): return form.rawValue
+ default: return value
+ }
+ }
+}
+
+extension Attribute: Equatable { }
+
+public func == (lhs: Attribute, rhs: Attribute) -> Bool {
+ return (lhs.foundationValue as? NSObject) == (rhs.foundationValue as? NSObject)
+}
diff --git a/SwiftyAttributes/Sources/common/AttributeName.swift b/SwiftyAttributes/Sources/common/AttributeName.swift
new file mode 100644
index 0000000..37d8892
--- /dev/null
+++ b/SwiftyAttributes/Sources/common/AttributeName.swift
@@ -0,0 +1,181 @@
+//
+// AttributeName.swift
+// SwiftyAttributes
+//
+// Created by Eddie Kaiger on 11/23/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+#if os(macOS)
+ import AppKit
+#else
+ import UIKit
+#endif
+
+extension Attribute {
+
+ /**
+ An enum that corresponds to `Attribute`, mapping attributes to their respective names.
+ */
+ public enum Name: RawRepresentable {
+ #if os(watchOS)
+ #else
+ case attachment
+ #endif
+ case baselineOffset
+ case backgroundColor
+ #if os(macOS)
+ case cursor
+ #endif
+ case expansion
+ case font
+ case kern
+ case ligature
+ case link
+ #if os(macOS)
+ case markedClauseSegment
+ #endif
+ case obliqueness
+ case paragraphStyle
+ #if os(watchOS)
+ #else
+ case shadow
+ #endif
+ #if os(macOS)
+ case spellingState
+ #endif
+ case strokeColor
+ case strokeWidth
+ case strikethroughColor
+ case strikethroughStyle
+ #if os(macOS)
+ case superscript
+ case textAlternatives
+ #endif
+ case textColor
+ case textEffect
+ #if os(macOS)
+ case toolTip
+ #endif
+ case underlineColor
+ case underlineStyle
+ case verticalGlyphForm
+ case writingDirection
+
+ public init?(rawValue: String) {
+
+ #if os(macOS)
+ switch rawValue {
+ case NSCursorAttributeName:
+ self = .cursor
+ return
+ case NSMarkedClauseSegmentAttributeName:
+ self = .markedClauseSegment
+ return
+ case NSSpellingStateAttributeName:
+ self = .spellingState
+ return
+ case NSSuperscriptAttributeName:
+ self = .superscript
+ return
+ case NSTextAlternativesAttributeName:
+ self = .textAlternatives
+ return
+ case NSToolTipAttributeName:
+ self = .toolTip
+ return
+ default: break
+ }
+ #endif
+
+ switch rawValue {
+ case NSAttachmentAttributeName:
+ #if os(watchOS)
+ return nil
+ #else
+ self = .attachment
+ #endif
+ case NSBaselineOffsetAttributeName: self = .baselineOffset
+ case NSBackgroundColorAttributeName: self = .backgroundColor
+ case NSExpansionAttributeName: self = .expansion
+ case NSFontAttributeName: self = .font
+ case NSKernAttributeName: self = .kern
+ case NSLigatureAttributeName: self = .ligature
+ case NSLinkAttributeName: self = .link
+ case NSObliquenessAttributeName: self = .obliqueness
+ case NSParagraphStyleAttributeName: self = .paragraphStyle
+ case NSShadowAttributeName:
+ #if os(watchOS)
+ return nil
+ #else
+ self = .shadow
+ #endif
+ case NSStrokeColorAttributeName: self = .strokeColor
+ case NSStrokeWidthAttributeName: self = .strokeWidth
+ case NSStrikethroughColorAttributeName: self = .strikethroughColor
+ case NSStrikethroughStyleAttributeName: self = .strikethroughStyle
+ case NSForegroundColorAttributeName: self = .textColor
+ case NSTextEffectAttributeName: self = .textEffect
+ case NSUnderlineColorAttributeName: self = .underlineColor
+ case NSUnderlineStyleAttributeName: self = .underlineStyle
+ case NSVerticalGlyphFormAttributeName: self = .verticalGlyphForm
+ case NSWritingDirectionAttributeName: self = .writingDirection
+ default: return nil
+ }
+ }
+
+ public var rawValue: String {
+
+ var name: String!
+
+ // Bug in Swift prevents us from putting directives inside switch statements (https://bugs.swift.org/browse/SR-2)
+
+ #if os(watchOS)
+ #else
+ switch self {
+ case .attachment: name = NSAttachmentAttributeName
+ case .shadow: name = NSShadowAttributeName
+ default: break
+ }
+ #endif
+
+ #if os(macOS)
+ switch self {
+ case .cursor: name = NSCursorAttributeName
+ case .markedClauseSegment: name = NSMarkedClauseSegmentAttributeName
+ case .spellingState: name = NSSpellingStateAttributeName
+ case .superscript: name = NSSuperscriptAttributeName
+ case .textAlternatives: name = NSTextAlternativesAttributeName
+ case .toolTip: name = NSToolTipAttributeName
+ default: break
+ }
+ #endif
+
+ switch self {
+ case .baselineOffset: name = NSBaselineOffsetAttributeName
+ case .backgroundColor: name = NSBackgroundColorAttributeName
+ case .expansion: name = NSExpansionAttributeName
+ case .font: name = NSFontAttributeName
+ case .kern: name = NSKernAttributeName
+ case .ligature: name = NSLigatureAttributeName
+ case .link: name = NSLinkAttributeName
+ case .obliqueness: name = NSObliquenessAttributeName
+ case .paragraphStyle: name = NSParagraphStyleAttributeName
+ case .strokeColor: name = NSStrokeColorAttributeName
+ case .strokeWidth: name = NSStrokeWidthAttributeName
+ case .strikethroughColor: name = NSStrikethroughColorAttributeName
+ case .strikethroughStyle: name = NSStrikethroughStyleAttributeName
+ case .textColor: name = NSForegroundColorAttributeName
+ case .textEffect: name = NSTextEffectAttributeName
+ case .underlineColor: name = NSUnderlineColorAttributeName
+ case .underlineStyle: name = NSUnderlineStyleAttributeName
+ case .verticalGlyphForm: name = NSVerticalGlyphFormAttributeName
+ case .writingDirection: name = NSWritingDirectionAttributeName
+ default: break
+ }
+
+ return name
+ }
+ }
+
+}
diff --git a/SwiftyAttributes/Ligatures.swift b/SwiftyAttributes/Sources/common/Ligatures.swift
similarity index 100%
rename from SwiftyAttributes/Ligatures.swift
rename to SwiftyAttributes/Sources/common/Ligatures.swift
diff --git a/SwiftyAttributes/NSAttributedString+SwiftyAttributes.swift b/SwiftyAttributes/Sources/common/NSAttributedString+SwiftyAttributes.swift
similarity index 63%
rename from SwiftyAttributes/NSAttributedString+SwiftyAttributes.swift
rename to SwiftyAttributes/Sources/common/NSAttributedString+SwiftyAttributes.swift
index 0ba088d..2116d0e 100644
--- a/SwiftyAttributes/NSAttributedString+SwiftyAttributes.swift
+++ b/SwiftyAttributes/Sources/common/NSAttributedString+SwiftyAttributes.swift
@@ -71,24 +71,73 @@ extension NSAttributedString {
- If the named attribute exists at `location`, upon return `range` contains a range over which the named attribute’s value applies.
- If the named attribute does not exist at `location`, upon return `range` contains the range over which the attribute does not exist.
- The range isn’t necessarily the maximum range covered by `attrName`, and its extent is implementation-dependent. If you need the maximum range, use attribute(_:at:longestEffectiveRange:in:). If you don't need this value, pass `nil`.
+ The range isn’t necessarily the maximum range covered by `attrName`, and its extent is implementation-dependent.
+ If you need the maximum range, use attribute(_:at:longestEffectiveRange:in:). If you don't need this value, pass `nil`.
*/
public func attribute(_ attrName: Attribute.Name, at location: Int, effectiveRange range: NSRangePointer? = nil) -> Attribute? {
- if let attr = attribute(attrName.rawValue, at: location, effectiveRange: range) {
- let attributeValue: Any
- switch attrName {
- case .ligature: attributeValue = Ligatures(rawValue: attr as! Int)!
- case .strikethroughStyle: attributeValue = NSUnderlineStyle(rawValue: attr as! Int)!
- case .textEffect: attributeValue = TextEffect(rawValue: attr as! String)!
- case .underlineStyle: attributeValue = NSUnderlineStyle(rawValue: attr as! Int)!
- case .writingDirection: attributeValue = (attr as! [Int]).map(WritingDirection.init)
- default: attributeValue = attr
- }
- return Attribute(name: attrName, value: attributeValue)
+ if let attributeValue = attribute(attrName.rawValue, at: location, effectiveRange: range) {
+ return Attribute(name: attrName, foundationValue: attributeValue)
}
return nil
}
+ /**
+ Returns the enumerated attributes in a specified range as an array of attribute-range pairs.
+
+ - parameters:
+ - range: Contains the maximum range over which the attributes are enumerated.
+ - options: The options used by the enumeration. The values can be combined using C-bitwise OR. The values are described in `NSAttributedString.EnumerationOptions`.
+ - returns: An array of attribute-range tuples. Each tuples contains a range and the array of attributes that exist in that range.
+ */
+ public func attributes(in range: Range, options: NSAttributedString.EnumerationOptions = []) -> [([Attribute], Range)] {
+ var attributeRanges = [([Attribute], Range)]()
+ enumerateAttributes(in: range, options: options) { attributes, range, _ in
+ attributeRanges.append((attributes, range))
+ }
+ return attributeRanges
+ }
+
+ /**
+ Executes the block for each attribute in the range. For discussion, see documentation for `NSAttributedString.enumerateAttributes(in:options:using:)`.
+
+ - parameters:
+
+ - enumerationRange: Contains the maximum range over which the attributes and values are enumerated, clipped to enumerationRange.
+ - options: The options used by the enumeration. The values can be combined using C-bitwise OR. The values are described in `NSAttributedString.EnumerationOptions`.
+ - block: The block to apply to ranges of the attribute in the attributed string. The block takes three arguments:
+
+ + attrs: The attributes for the range.
+ + range: The run of the attributes.
+ + stop: A reference to a Boolean value. The block can set the value to `true` to stop further processing of the set.
+ The stop argument is an out-only argument. You should only ever set this Boolean to `true` within the block.
+ */
+ public func enumerateAttributes(in enumerationRange: Range, options: NSAttributedString.EnumerationOptions = [], using block: (_ attrs: [Attribute], _ range: Range, _ stop: UnsafeMutablePointer) -> Void) {
+ enumerateAttributes(in: NSRange(enumerationRange), options: options) { attributes, range, ptr in
+ block(attributes.swiftyAttributes, range.location ..< (range.location + range.length), ptr)
+ }
+ }
+
+ /**
+ Executes the block for the specified attribute run in the specified range. For discussion, see documentation for `NSAttributedString.enumerateAttribute(_:in:options:using:)`.
+
+ - parameters:
+
+ - attrName: The name of an attribute.
+ - enumerationRange: Contains the maximum range over which the attributes and values are enumerated, clipped to enumerationRange.
+ - options: The options used by the enumeration. The values can be combined using C-bitwise OR. The values are described in `NSAttributedString.EnumerationOptions`.
+ - block: The block to apply to ranges of the attribute in the attributed string. The block takes three arguments:
+
+ + value: The value of the attribute.
+ + range: A range containing the run of the attribute.
+ + stop: A reference to a Boolean value. The block can set the value to `true` to stop further processing of the set.
+ The stop argument is an out-only argument. You should only ever set this Boolean to `true` within the block.
+ */
+ public func enumerateAttribute(_ attrName: Attribute.Name, in enumerationRange: Range, options: NSAttributedString.EnumerationOptions = [], using block: (_ value: Any?, _ range: Range, _ stop: UnsafeMutablePointer) -> Void) {
+ enumerateAttribute(attrName.rawValue, in: NSRange(enumerationRange), options: options) { value, range, ptr in
+ block(value, range.location ..< (range.location + range.length), ptr)
+ }
+ }
+
}
extension NSAttributedString {
@@ -99,7 +148,7 @@ extension NSAttributedString {
- parameter font: The font to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withFont(_ font: UIFont) -> NSMutableAttributedString {
+ public func withFont(_ font: Font) -> NSMutableAttributedString {
return withAttribute(.font(font))
}
@@ -109,7 +158,7 @@ extension NSAttributedString {
- parameter style: The font to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withParagraphStyle(_ style: NSParagraphStyle) -> NSMutableAttributedString {
+ public func withParagraphStyle(_ style: ParagraphStyle) -> NSMutableAttributedString {
return withAttribute(.paragraphStyle(style))
}
@@ -119,7 +168,7 @@ extension NSAttributedString {
- parameter color: The text color to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withTextColor(_ color: UIColor) -> NSMutableAttributedString {
+ public func withTextColor(_ color: Color) -> NSMutableAttributedString {
return withAttribute(.textColor(color))
}
@@ -129,7 +178,7 @@ extension NSAttributedString {
- parameter color: The background color to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withBackgroundColor(_ color: UIColor) -> NSMutableAttributedString {
+ public func withBackgroundColor(_ color: Color) -> NSMutableAttributedString {
return withAttribute(.backgroundColor(color))
}
@@ -159,7 +208,7 @@ extension NSAttributedString {
- parameter style: The strikethrough style to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withStrikethroughStyle(_ style: NSUnderlineStyle) -> NSMutableAttributedString {
+ public func withStrikethroughStyle(_ style: UnderlineStyle) -> NSMutableAttributedString {
return withAttribute(.strikethroughStyle(style))
}
@@ -169,7 +218,7 @@ extension NSAttributedString {
- parameter style: The underline style to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withUnderlineStyle(_ style: NSUnderlineStyle) -> NSMutableAttributedString {
+ public func withUnderlineStyle(_ style: UnderlineStyle) -> NSMutableAttributedString {
return withAttribute(.underlineStyle(style))
}
@@ -179,7 +228,7 @@ extension NSAttributedString {
- parameter color: The stroke color to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withStrokeColor(_ color: UIColor) -> NSMutableAttributedString {
+ public func withStrokeColor(_ color: Color) -> NSMutableAttributedString {
return withAttribute(.strokeColor(color))
}
@@ -193,15 +242,18 @@ extension NSAttributedString {
return withAttribute(.strokeWidth(width))
}
+ #if os(watchOS)
+ #else
/**
Creates an attributed string with a specific shadow.
- parameter shadow: The shadow to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withShadow(_ shadow: NSShadow) -> NSMutableAttributedString {
+ public func withShadow(_ shadow: Shadow) -> NSMutableAttributedString {
return withAttribute(.shadow(shadow))
}
+ #endif
/**
Creates an attributed string with a specific text effect.
@@ -213,15 +265,18 @@ extension NSAttributedString {
return withAttribute(.textEffect(effect))
}
+ #if os(watchOS)
+ #else
/**
Creates an attributed string with a specific attachment.
- parameter attachment: The attachment to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withAttachment(_ attachment: NSTextAttachment) -> NSMutableAttributedString {
+ public func withAttachment(_ attachment: TextAttachment) -> NSMutableAttributedString {
return withAttribute(.attachment(attachment))
}
+ #endif
/**
Creates an attributed string with a specific link.
@@ -249,7 +304,7 @@ extension NSAttributedString {
- parameter color: The underline color to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withUnderlineColor(_ color: UIColor) -> NSMutableAttributedString {
+ public func withUnderlineColor(_ color: Color) -> NSMutableAttributedString {
return withAttribute(.underlineColor(color))
}
@@ -259,7 +314,7 @@ extension NSAttributedString {
- parameter color: The underline style to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withStrikethroughColor(_ color: UIColor) -> NSMutableAttributedString {
+ public func withStrikethroughColor(_ color: Color) -> NSMutableAttributedString {
return withAttribute(.strikethroughColor(color))
}
@@ -283,6 +338,16 @@ extension NSAttributedString {
return withAttribute(.expansion(expansion))
}
+ /**
+ Creates an attributed string with a specific vertical glyph form (horizontal or vertical writing direction).
+
+ - parameter form: The horizontal/vertical writing direction to set for the attributed string. See `VerticalGlyphForm` for details.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withVerticalGlyphForm(_ form: VerticalGlyphForm) -> NSMutableAttributedString {
+ return withAttribute(.verticalGlyphForm(form))
+ }
+
/**
Creates an attributed string with a specific writing direction.
diff --git a/SwiftyAttributes/NSMutableAttributedString+SwiftyAttributes.swift b/SwiftyAttributes/Sources/common/NSMutableAttributedString+SwiftyAttributes.swift
similarity index 100%
rename from SwiftyAttributes/NSMutableAttributedString+SwiftyAttributes.swift
rename to SwiftyAttributes/Sources/common/NSMutableAttributedString+SwiftyAttributes.swift
diff --git a/SwiftyAttributes/Operators.swift b/SwiftyAttributes/Sources/common/Operators.swift
similarity index 100%
rename from SwiftyAttributes/Operators.swift
rename to SwiftyAttributes/Sources/common/Operators.swift
diff --git a/SwiftyAttributes/String+SwiftyAttributes.swift b/SwiftyAttributes/Sources/common/String+SwiftyAttributes.swift
similarity index 72%
rename from SwiftyAttributes/String+SwiftyAttributes.swift
rename to SwiftyAttributes/Sources/common/String+SwiftyAttributes.swift
index 907d30d..cf31837 100644
--- a/SwiftyAttributes/String+SwiftyAttributes.swift
+++ b/SwiftyAttributes/Sources/common/String+SwiftyAttributes.swift
@@ -30,22 +30,23 @@ extension String {
return attributedString.withAttribute(attribute)
}
+ /// Creates a mutable attributed string with the given string.
+ public var attributedString: NSMutableAttributedString {
+ return NSMutableAttributedString(string: self)
+ }
+
}
extension String {
- fileprivate var attributedString: NSAttributedString {
- return NSAttributedString(string: self)
- }
-
/**
Creates an attributed string with a specific font.
- parameter font: The font to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withFont(_ font: UIFont) -> NSMutableAttributedString {
- return attributedString.withFont(font)
+ public func withFont(_ font: Font) -> NSMutableAttributedString {
+ return withAttribute(.font(font))
}
/**
@@ -54,8 +55,8 @@ extension String {
- parameter style: The font to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withParagraphStyle(_ style: NSParagraphStyle) -> NSMutableAttributedString {
- return attributedString.withParagraphStyle(style)
+ public func withParagraphStyle(_ style: ParagraphStyle) -> NSMutableAttributedString {
+ return withAttribute(.paragraphStyle(style))
}
/**
@@ -64,8 +65,8 @@ extension String {
- parameter color: The text color to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withTextColor(_ color: UIColor) -> NSMutableAttributedString {
- return attributedString.withTextColor(color)
+ public func withTextColor(_ color: Color) -> NSMutableAttributedString {
+ return withAttribute(.textColor(color))
}
/**
@@ -74,8 +75,8 @@ extension String {
- parameter color: The background color to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withBackgroundColor(_ color: UIColor) -> NSMutableAttributedString {
- return attributedString.withBackgroundColor(color)
+ public func withBackgroundColor(_ color: Color) -> NSMutableAttributedString {
+ return withAttribute(.backgroundColor(color))
}
/**
@@ -85,7 +86,7 @@ extension String {
- returns: A new attributed string with the newly added attribute.
*/
public func withLigatures(_ ligatures: Ligatures) -> NSMutableAttributedString {
- return attributedString.withLigatures(ligatures)
+ return withAttribute(.ligatures(ligatures))
}
/**
@@ -95,7 +96,7 @@ extension String {
- returns: A new attributed string with the newly added attribute.
*/
public func withKern(_ kernValue: Double) -> NSMutableAttributedString {
- return attributedString.withKern(kernValue)
+ return withAttribute(.kern(kernValue))
}
/**
@@ -104,8 +105,8 @@ extension String {
- parameter style: The strikethrough style to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withStrikethroughStyle(_ style: NSUnderlineStyle) -> NSMutableAttributedString {
- return attributedString.withStrikethroughStyle(style)
+ public func withStrikethroughStyle(_ style: StrikethroughStyle) -> NSMutableAttributedString {
+ return withAttribute(.strikethroughStyle(style))
}
/**
@@ -114,8 +115,8 @@ extension String {
- parameter style: The underline style to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withUnderlineStyle(_ style: NSUnderlineStyle) -> NSMutableAttributedString {
- return attributedString.withUnderlineStyle(style)
+ public func withUnderlineStyle(_ style: UnderlineStyle) -> NSMutableAttributedString {
+ return withAttribute(.underlineStyle(style))
}
/**
@@ -124,8 +125,8 @@ extension String {
- parameter color: The stroke color to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withStrokeColor(_ color: UIColor) -> NSMutableAttributedString {
- return attributedString.withStrokeColor(color)
+ public func withStrokeColor(_ color: Color) -> NSMutableAttributedString {
+ return withAttribute(.strokeColor(color))
}
/**
@@ -135,17 +136,7 @@ extension String {
- returns: A new attributed string with the newly added attribute.
*/
public func withStrokeWidth(_ width: Double) -> NSMutableAttributedString {
- return attributedString.withStrokeWidth(width)
- }
-
- /**
- Creates an attributed string with a specific shadow.
-
- - parameter shadow: The shadow to set for the attributed string.
- - returns: A new attributed string with the newly added attribute.
- */
- public func withShadow(_ shadow: NSShadow) -> NSMutableAttributedString {
- return attributedString.withShadow(shadow)
+ return withAttribute(.strokeWidth(width))
}
/**
@@ -155,17 +146,7 @@ extension String {
- returns: A new attributed string with the newly added attribute.
*/
public func withTextEffect(_ effect: TextEffect) -> NSMutableAttributedString {
- return attributedString.withTextEffect(effect)
- }
-
- /**
- Creates an attributed string with a specific attachment.
-
- - parameter attachment: The attachment to set for the attributed string.
- - returns: A new attributed string with the newly added attribute.
- */
- public func withAttachment(_ attachment: NSTextAttachment) -> NSMutableAttributedString {
- return attributedString.withAttachment(attachment)
+ return withAttribute(.textEffect(effect))
}
/**
@@ -175,7 +156,7 @@ extension String {
- returns: A new attributed string with the newly added attribute.
*/
public func withLink(_ link: URL) -> NSMutableAttributedString {
- return attributedString.withLink(link)
+ return withAttribute(.link(link))
}
/**
@@ -185,7 +166,7 @@ extension String {
- returns: A new attributed string with the newly added attribute.
*/
public func withBaselineOffset(_ offset: Double) -> NSMutableAttributedString {
- return attributedString.withBaselineOffset(offset)
+ return withAttribute(.baselineOffset(offset))
}
/**
@@ -194,8 +175,8 @@ extension String {
- parameter color: The underline color to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withUnderlineColor(_ color: UIColor) -> NSMutableAttributedString {
- return attributedString.withUnderlineColor(color)
+ public func withUnderlineColor(_ color: Color) -> NSMutableAttributedString {
+ return withAttribute(.underlineColor(color))
}
/**
@@ -204,8 +185,8 @@ extension String {
- parameter color: The underline style to set for the attributed string.
- returns: A new attributed string with the newly added attribute.
*/
- public func withStrikethroughColor(_ color: UIColor) -> NSMutableAttributedString {
- return attributedString.withStrikethroughColor(color)
+ public func withStrikethroughColor(_ color: Color) -> NSMutableAttributedString {
+ return withAttribute(.strikethroughColor(color))
}
/**
@@ -215,7 +196,7 @@ extension String {
- returns: A new attributed string with the newly added attribute.
*/
public func withObliqueness(_ obliquenessValue: Double) -> NSMutableAttributedString {
- return attributedString.withObliqueness(obliquenessValue)
+ return withAttribute(.obliqueness(obliquenessValue))
}
/**
@@ -225,7 +206,7 @@ extension String {
- returns: A new attributed string with the newly added attribute.
*/
public func withExpansion(_ expansion: Double) -> NSMutableAttributedString {
- return attributedString.withExpansion(expansion)
+ return withAttribute(.expansion(expansion))
}
/**
@@ -235,7 +216,42 @@ extension String {
- returns: A new attributed string with the newly added attribute.
*/
public func withWritingDirections(_ directions: [WritingDirection]) -> NSMutableAttributedString {
- return attributedString.withWritingDirections(directions)
+ return withAttribute(.writingDirections(directions))
+ }
+
+ /**
+ Creates an attributed string with a specific vertical glyph form (horizontal or vertical writing direction).
+
+ - parameter form: The horizontal/vertical writing direction to set for the attributed string. See `VerticalGlyphForm` for details.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withVerticalGlyphForm(_ form: VerticalGlyphForm) -> NSMutableAttributedString {
+ return withAttribute(.verticalGlyphForm(form))
+ }
+
+ #if os(watchOS)
+ #else
+
+ /**
+ Creates an attributed string with a specific shadow.
+
+ - parameter shadow: The shadow to set for the attributed string.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withShadow(_ shadow: Shadow) -> NSMutableAttributedString {
+ return withAttribute(.shadow(shadow))
}
+ /**
+ Creates an attributed string with a specific attachment.
+
+ - parameter attachment: The attachment to set for the attributed string.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withAttachment(_ attachment: TextAttachment) -> NSMutableAttributedString {
+ return withAttribute(.attachment(attachment))
+ }
+
+ #endif
+
}
diff --git a/SwiftyAttributes/TextEffect.swift b/SwiftyAttributes/Sources/common/TextEffect.swift
similarity index 92%
rename from SwiftyAttributes/TextEffect.swift
rename to SwiftyAttributes/Sources/common/TextEffect.swift
index b9a51e6..f6562ca 100644
--- a/SwiftyAttributes/TextEffect.swift
+++ b/SwiftyAttributes/Sources/common/TextEffect.swift
@@ -6,7 +6,11 @@
// Copyright © 2016 Eddie Kaiger. All rights reserved.
//
-import Foundation
+#if os(macOS)
+ import AppKit
+#else
+ import UIKit
+#endif
/**
An enum describing the possible values for text effects on attributed strings.
diff --git a/SwiftyAttributes/Sources/common/VerticalGlyphForm.swift b/SwiftyAttributes/Sources/common/VerticalGlyphForm.swift
new file mode 100644
index 0000000..f501f3c
--- /dev/null
+++ b/SwiftyAttributes/Sources/common/VerticalGlyphForm.swift
@@ -0,0 +1,23 @@
+//
+// VerticalGlyphForm.swift
+// SwiftyAttributes
+//
+// Created by Eddie Kaiger on 11/16/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+import Foundation
+
+/**
+ An enum to indicate horizontal or vertical writing direction. On iOS, only horizontal form is valid.
+ */
+public enum VerticalGlyphForm: Int {
+
+ /// Horizontal writing direction.
+ case horizontal = 0
+
+ #if os(macOS)
+ /// Vertical writing direction.
+ case vertical = 1
+ #endif
+}
diff --git a/SwiftyAttributes/WritingDirection.swift b/SwiftyAttributes/Sources/common/WritingDirection.swift
similarity index 91%
rename from SwiftyAttributes/WritingDirection.swift
rename to SwiftyAttributes/Sources/common/WritingDirection.swift
index e47ad11..8368664 100644
--- a/SwiftyAttributes/WritingDirection.swift
+++ b/SwiftyAttributes/Sources/common/WritingDirection.swift
@@ -6,9 +6,13 @@
// Copyright © 2016 Eddie Kaiger. All rights reserved.
//
-import UIKit
+#if os(macOS)
+ import AppKit
+#else
+ import UIKit
+#endif
-@available(iOS 9.0, *)
+@available(iOS 9.0, OSX 10.11, *)
private func mappingValue(direction: NSWritingDirection, formatType: NSWritingDirectionFormatType) -> Int {
return direction.rawValue | formatType.rawValue
}
@@ -31,7 +35,7 @@ public enum WritingDirection: RawRepresentable {
case rightToLeftEmbedding
public init?(rawValue: Int) {
- guard #available(iOS 9.0, *) else { return nil }
+ guard #available(iOS 9.0, macOS 10.11, *) else { return nil }
switch rawValue {
case mappingValue(direction: .leftToRight, formatType: .override): self = .leftToRightOverride
case mappingValue(direction: .rightToLeft, formatType: .override): self = .rightToLeftOverride
@@ -42,7 +46,7 @@ public enum WritingDirection: RawRepresentable {
}
public var rawValue: Int {
- guard #available(iOS 9.0, *) else { return 0 }
+ guard #available(iOS 9.0, macOS 10.11, *) else { return 0 }
switch self {
case .leftToRightOverride: return mappingValue(direction: .leftToRight, formatType: .override)
case .rightToLeftOverride: return mappingValue(direction: .rightToLeft, formatType: .override)
diff --git a/SwiftyAttributes/Sources/macOS/NSAttributedString+macOS.swift b/SwiftyAttributes/Sources/macOS/NSAttributedString+macOS.swift
new file mode 100644
index 0000000..b98ff0e
--- /dev/null
+++ b/SwiftyAttributes/Sources/macOS/NSAttributedString+macOS.swift
@@ -0,0 +1,93 @@
+//
+// NSAttributedString+macOS.swift
+// SwiftyAttributes
+//
+// Created by Eddie Kaiger on 11/17/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+#if os(macOS)
+import AppKit
+
+extension NSAttributedString {
+
+ /**
+ Creates an attributed string with a cursor object.
+
+ - parameter cursor: The cursor to set for the attributed string.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withCursor(_ cursor: Cursor) -> NSMutableAttributedString {
+ return withAttribute(.cursor(cursor))
+ }
+
+ /**
+ Creates an attributed string with the specified marked clause segment.
+
+ - parameter markedClauseSegment: The index in marked text indicating clause segments.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withMarkedClauseSegment(_ segment: Int) -> NSMutableAttributedString {
+ return withAttribute(.markedClauseSegment(segment))
+ }
+
+ /**
+ Creates an attributed string with the specified spelling state.
+
+ - parameter state: A state indicating a spelling or grammar error. See `SpellingState` for possible values.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withSpellingState(_ state: SpellingState) -> NSMutableAttributedString {
+ return withAttribute(.spellingState(state))
+ }
+
+ /**
+ Creates an attributed string with the specified superscript value.
+
+ - parameter superscript: The superscript to set for the attributed string.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withSuperscript(_ superscript: Int) -> NSMutableAttributedString {
+ return withAttribute(.superscript(superscript))
+ }
+
+ /**
+ Creates an attributed string with the specified text alternatives object.
+
+ - parameter textAlternatives: The NSTextAlternatives object representing alternatives for a string that may be presented to the user.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withTextAlternatives(_ textAlternatives: TextAlternatives) -> NSMutableAttributedString {
+ return withAttribute(.textAlternatives(textAlternatives))
+ }
+
+ /**
+ Creates an attributed string with a tooltip message.
+
+ - parameter toolTip: The toolTip message to set for the attributed string.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withToolTip(_ toolTip: String) -> NSMutableAttributedString {
+ return withAttribute(.toolTip(toolTip))
+ }
+
+}
+
+extension NSAttributedString {
+
+ /**
+ Returns the font attributes in effect for the character at the given location.
+ */
+ public func fontAttributes(in range: Range) -> [Attribute] {
+ return fontAttributes(in: NSRange(range)).swiftyAttributes
+ }
+
+ /**
+ Returns the ruler (paragraph) attributes in effect for the characters within the given range.
+ */
+ public func rulerAttributes(in range: Range) -> [Attribute] {
+ return rulerAttributes(in: NSRange(range)).swiftyAttributes
+ }
+
+}
+#endif
diff --git a/SwiftyAttributes/Sources/macOS/SpellingState.swift b/SwiftyAttributes/Sources/macOS/SpellingState.swift
new file mode 100644
index 0000000..ccab115
--- /dev/null
+++ b/SwiftyAttributes/Sources/macOS/SpellingState.swift
@@ -0,0 +1,45 @@
+//
+// SpellingState.swift
+// SwiftyAttributes
+//
+// Created by Eddie Kaiger on 11/16/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+#if os(macOS)
+import AppKit
+
+/**
+ This enum controls the display of the spelling and grammar indicators on text,
+ highlighting portions of the text that are flagged for spelling or grammar issues.
+ This should be used with `Attribute.spellingState`.
+ */
+public enum SpellingState: RawRepresentable {
+
+ /// No spelling or grammar indicator.
+ case none
+
+ /// The spelling error indicator.
+ case spellingFlag
+
+ /// The grammar error indicator.
+ case grammarFlag
+
+ public init?(rawValue: Int) {
+ switch rawValue {
+ case 0: self = .none
+ case NSSpellingStateSpellingFlag: self = .spellingFlag
+ case NSSpellingStateGrammarFlag: self = .grammarFlag
+ default: return nil
+ }
+ }
+
+ public var rawValue: Int {
+ switch self {
+ case .none: return 0
+ case .spellingFlag: return NSSpellingStateSpellingFlag
+ case .grammarFlag: return NSSpellingStateGrammarFlag
+ }
+ }
+}
+#endif
diff --git a/SwiftyAttributes/Sources/macOS/String+macOS.swift b/SwiftyAttributes/Sources/macOS/String+macOS.swift
new file mode 100644
index 0000000..b9cfa63
--- /dev/null
+++ b/SwiftyAttributes/Sources/macOS/String+macOS.swift
@@ -0,0 +1,77 @@
+//
+// String+macOS.swift
+// SwiftyAttributes
+//
+// Created by Eddie Kaiger on 11/29/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+
+#if os(macOS)
+import AppKit
+
+extension String {
+
+ /**
+ Creates an attributed string with a cursor object.
+
+ - parameter cursor: The cursor to set for the attributed string.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withCursor(_ cursor: Cursor) -> NSMutableAttributedString {
+ return withAttribute(.cursor(cursor))
+ }
+
+ /**
+ Creates an attributed string with the specified marked clause segment.
+
+ - parameter markedClauseSegment: The index in marked text indicating clause segments.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withMarkedClauseSegment(_ segment: Int) -> NSMutableAttributedString {
+ return withAttribute(.markedClauseSegment(segment))
+ }
+
+ /**
+ Creates an attributed string with the specified spelling state.
+
+ - parameter state: A state indicating a spelling or grammar error. See `SpellingState` for possible values.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withSpellingState(_ state: SpellingState) -> NSMutableAttributedString {
+ return withAttribute(.spellingState(state))
+ }
+
+ /**
+ Creates an attributed string with the specified superscript value.
+
+ - parameter superscript: The superscript to set for the attributed string.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withSuperscript(_ superscript: Int) -> NSMutableAttributedString {
+ return withAttribute(.superscript(superscript))
+ }
+
+ /**
+ Creates an attributed string with the specified text alternatives object.
+
+ - parameter textAlternatives: The NSTextAlternatives object representing alternatives for a string that may be presented to the user.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withTextAlternatives(_ textAlternatives: TextAlternatives) -> NSMutableAttributedString {
+ return withAttribute(.textAlternatives(textAlternatives))
+ }
+
+ /**
+ Creates an attributed string with a tooltip message.
+
+ - parameter toolTip: The toolTip message to set for the attributed string.
+ - returns: A new attributed string with the newly added attribute.
+ */
+ public func withToolTip(_ toolTip: String) -> NSMutableAttributedString {
+ return withAttribute(.toolTip(toolTip))
+ }
+
+}
+
+#endif
diff --git a/SwiftyAttributes/SwiftyAttributes.h b/SwiftyAttributes/SwiftyAttributes.h
index 0be1806..6ef1eb6 100644
--- a/SwiftyAttributes/SwiftyAttributes.h
+++ b/SwiftyAttributes/SwiftyAttributes.h
@@ -2,18 +2,11 @@
// SwiftyAttributes.h
// SwiftyAttributes
//
-// Created by Eddie Kaiger on 9/30/16.
+// Created by Eddie Kaiger on 11/9/16.
// Copyright © 2016 Eddie Kaiger. All rights reserved.
//
-#import
+#import
-//! Project version number for SwiftyAttributes.
FOUNDATION_EXPORT double SwiftyAttributesVersionNumber;
-
-//! Project version string for SwiftyAttributes.
FOUNDATION_EXPORT const unsigned char SwiftyAttributesVersionString[];
-
-// In this header, you should import all the public headers of your framework using statements like #import
-
-
diff --git a/SwiftyAttributesTests/Attribute+Sequence_Tests.swift b/SwiftyAttributesTests/Attribute+Sequence_Tests.swift
new file mode 100644
index 0000000..dc2efa5
--- /dev/null
+++ b/SwiftyAttributesTests/Attribute+Sequence_Tests.swift
@@ -0,0 +1,55 @@
+//
+// Attribute+Sequence_Tests.swift
+// SwiftyAttributes
+//
+// Created by Eddie Kaiger on 11/26/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+import XCTest
+import SwiftyAttributes
+
+class Attribute_Sequence_Tests: XCTestCase {
+
+ func testDictionaryToSwiftyAttributes() {
+ let dict: [String: Any] = [
+ NSBaselineOffsetAttributeName: 3.2,
+ NSExpansionAttributeName: 5,
+ NSUnderlineStyleAttributeName: NSUnderlineStyle.styleDouble.rawValue
+ ]
+ let sort: (Attribute, Attribute) -> Bool = { $0.0.keyName < $0.1.keyName }
+ let expected: [Attribute] = [
+ .baselineOffset(3.2),
+ .expansion(5),
+ .underlineStyle(.styleDouble)
+ ].sorted(by: sort)
+ XCTAssertEqual(dict.swiftyAttributes.sorted(by: sort), expected)
+ }
+
+ func testDictionaryToSwiftyAttributes_withInvalidValues() {
+ let dict: [String: Any] = [
+ NSBaselineOffsetAttributeName: 3.2,
+ NSUnderlineStyleAttributeName: NSUnderlineStyle.styleDouble.rawValue,
+ "Sah dude": 5
+ ]
+ let sort: (Attribute, Attribute) -> Bool = { $0.0.keyName < $0.1.keyName }
+ let expected: [Attribute] = [
+ .baselineOffset(3.2),
+ .underlineStyle(.styleDouble)
+ ].sorted(by: sort)
+ XCTAssertEqual(dict.swiftyAttributes.sorted(by: sort), expected)
+ }
+
+ func testAttributesArrayToFoundationDictionary() {
+ let attrs: [Attribute] = [
+ .kern(3.5),
+ .link(URL(string: "www.google.com")!)
+ ]
+ let expected: [String: Any] = [
+ NSKernAttributeName: 3.5,
+ NSLinkAttributeName: URL(string: "www.google.com")!
+ ]
+ XCTAssertEqual(expected as NSDictionary, attrs.foundationAttributes as NSDictionary)
+ }
+
+}
diff --git a/SwiftyAttributesTests/Attribute_Tests.swift b/SwiftyAttributesTests/Attribute_Tests.swift
index dfa7a55..3582456 100644
--- a/SwiftyAttributesTests/Attribute_Tests.swift
+++ b/SwiftyAttributesTests/Attribute_Tests.swift
@@ -32,6 +32,15 @@ class Attribute_Tests: XCTestCase {
XCTAssertEqual(Attribute.Name(rawValue: NSUnderlineColorAttributeName)!, .underlineColor)
XCTAssertEqual(Attribute.Name(rawValue: NSUnderlineStyleAttributeName)!, .underlineStyle)
XCTAssertEqual(Attribute.Name(rawValue: NSWritingDirectionAttributeName)!, .writingDirection)
+ XCTAssertEqual(Attribute.Name(rawValue: NSVerticalGlyphFormAttributeName)!, .verticalGlyphForm)
+ #if os(macOS)
+ XCTAssertEqual(Attribute.Name(rawValue: NSCursorAttributeName), .cursor)
+ XCTAssertEqual(Attribute.Name(rawValue: NSMarkedClauseSegmentAttributeName), .markedClauseSegment)
+ XCTAssertEqual(Attribute.Name(rawValue: NSSpellingStateAttributeName), .spellingState)
+ XCTAssertEqual(Attribute.Name(rawValue: NSSuperscriptAttributeName), .superscript)
+ XCTAssertEqual(Attribute.Name(rawValue: NSTextAlternativesAttributeName), .textAlternatives)
+ XCTAssertEqual(Attribute.Name(rawValue: NSToolTipAttributeName), .toolTip)
+ #endif
XCTAssertNil(Attribute.Name(rawValue: "SomeAttribute"))
}
diff --git a/SwiftyAttributesTests/NSAttributedString_Tests.swift b/SwiftyAttributesTests/NSAttributedString_Tests.swift
index 28030d4..d50d71b 100644
--- a/SwiftyAttributesTests/NSAttributedString_Tests.swift
+++ b/SwiftyAttributesTests/NSAttributedString_Tests.swift
@@ -13,7 +13,7 @@ class NSAttributedString_Tests: XCTestCase {
func testInit_withStringAndAttributes() {
let subject = NSAttributedString(string: "Hello World", attributes: [.strokeColor(.green), .strokeWidth(3)])
- let expected = NSAttributedString(string: "Hello World", attributes: [NSStrokeColorAttributeName: UIColor.green, NSStrokeWidthAttributeName: 3])
+ let expected = NSAttributedString(string: "Hello World", attributes: [NSStrokeColorAttributeName: Color.green, NSStrokeWidthAttributeName: 3])
XCTAssertEqual(subject, expected)
}
@@ -28,11 +28,15 @@ class NSAttributedString_Tests: XCTestCase {
// MARK: - Attribute At Location
func testAttributeAtLocation_attachment() {
- let attachment = NSTextAttachment()
- attachment.image = UIImage(named: "Star", in: Bundle(for: type(of: self)), compatibleWith: nil)!
+ let attachment = TextAttachment()
+ #if os(macOS)
+ attachment.image = NSImage()
+ #else
+ attachment.image = UIImage(named: "Star", in: Bundle(for: type(of: self)), compatibleWith: nil)!
+ #endif
let str = "Hello".withAttachment(attachment)
- let subject = str.attribute(.attachment, at: 0, effectiveRange: nil)!.value as! NSTextAttachment
- let expected = str.attribute(NSAttachmentAttributeName, at: 0, effectiveRange: nil) as! NSTextAttachment
+ let subject = str.attribute(.attachment, at: 0, effectiveRange: nil)!.value as! TextAttachment
+ let expected = str.attribute(NSAttachmentAttributeName, at: 0, effectiveRange: nil) as! TextAttachment
XCTAssertEqual(subject, expected)
XCTAssertEqual(subject, attachment)
}
@@ -47,24 +51,24 @@ class NSAttributedString_Tests: XCTestCase {
func testAttributeAtLocation_backgroundColor() {
let str = "Hello".withBackgroundColor(.blue)
- let subject = str.attribute(.backgroundColor, at: 0, effectiveRange: nil)!.value as! UIColor
- let expected = str.attribute(NSBackgroundColorAttributeName, at: 0, effectiveRange: nil) as! UIColor
+ let subject = str.attribute(.backgroundColor, at: 0, effectiveRange: nil)!.value as! Color
+ let expected = str.attribute(NSBackgroundColorAttributeName, at: 0, effectiveRange: nil) as! Color
XCTAssertEqual(subject, expected)
XCTAssertEqual(subject, .blue)
}
func testAttributeAtLocation_expansion() {
- let str = "Hello".withExpansion(5.1)
+ let str = "Hello".withExpansion(5)
let subject = str.attribute(.expansion, at: 0, effectiveRange: nil)!.value as! Double
let expected = str.attribute(NSExpansionAttributeName, at: 0, effectiveRange: nil) as! Double
XCTAssertEqual(subject, expected)
- XCTAssertEqual(subject, 5.1)
+ XCTAssertEqual(subject, 5)
}
func testAttributeAtLocation_font() {
let str = "Hello".withFont(.systemFont(ofSize: 26))
- let subject = str.attribute(.font, at: 0, effectiveRange: nil)!.value as! UIFont
- let expected = str.attribute(NSFontAttributeName, at: 0, effectiveRange: nil) as! UIFont
+ let subject = str.attribute(.font, at: 0, effectiveRange: nil)!.value as! Font
+ let expected = str.attribute(NSFontAttributeName, at: 0, effectiveRange: nil) as! Font
XCTAssertEqual(subject, expected)
XCTAssertEqual(subject, .systemFont(ofSize: 26))
}
@@ -107,26 +111,26 @@ class NSAttributedString_Tests: XCTestCase {
style.lineSpacing = 3.4
style.alignment = .right
let str = "Hello".withParagraphStyle(style)
- let subject = str.attribute(.paragraphStyle, at: 0, effectiveRange: nil)!.value as! NSParagraphStyle
- let expected = str.attribute(NSParagraphStyleAttributeName, at: 0, effectiveRange: nil) as! NSParagraphStyle
+ let subject = str.attribute(.paragraphStyle, at: 0, effectiveRange: nil)!.value as! ParagraphStyle
+ let expected = str.attribute(NSParagraphStyleAttributeName, at: 0, effectiveRange: nil) as! ParagraphStyle
XCTAssertEqual(subject, expected)
XCTAssertEqual(subject, style)
}
func testAttributeAtLocation_shadow() {
- let shadow = NSShadow()
+ let shadow = Shadow()
shadow.shadowOffset = CGSize(width: 3, height: 5)
let str = "Hello".withShadow(shadow)
- let subject = str.attribute(.shadow, at: 0, effectiveRange: nil)!.value as! NSShadow
- let expected = str.attribute(NSShadowAttributeName, at: 0, effectiveRange: nil) as! NSShadow
+ let subject = str.attribute(.shadow, at: 0, effectiveRange: nil)!.value as! Shadow
+ let expected = str.attribute(NSShadowAttributeName, at: 0, effectiveRange: nil) as! Shadow
XCTAssertEqual(subject, expected)
XCTAssertEqual(subject, shadow)
}
func testAttributeAtLocation_strokeColor() {
let str = "Hello".withStrokeColor(.magenta)
- let subject = str.attribute(.strokeColor, at: 0, effectiveRange: nil)!.value as! UIColor
- let expected = str.attribute(NSStrokeColorAttributeName, at: 0, effectiveRange: nil) as! UIColor
+ let subject = str.attribute(.strokeColor, at: 0, effectiveRange: nil)!.value as! Color
+ let expected = str.attribute(NSStrokeColorAttributeName, at: 0, effectiveRange: nil) as! Color
XCTAssertEqual(subject, expected)
XCTAssertEqual(subject, .magenta)
}
@@ -141,8 +145,8 @@ class NSAttributedString_Tests: XCTestCase {
func testAttributeAtLocation_strikethroughColor() {
let str = "Hello".withStrikethroughColor(.orange)
- let subject = str.attribute(.strikethroughColor, at: 0, effectiveRange: nil)!.value as! UIColor
- let expected = str.attribute(NSStrikethroughColorAttributeName, at: 0, effectiveRange: nil) as! UIColor
+ let subject = str.attribute(.strikethroughColor, at: 0, effectiveRange: nil)!.value as! Color
+ let expected = str.attribute(NSStrikethroughColorAttributeName, at: 0, effectiveRange: nil) as! Color
XCTAssertEqual(subject, expected)
XCTAssertEqual(subject, .orange)
}
@@ -157,8 +161,8 @@ class NSAttributedString_Tests: XCTestCase {
func testAttributeAtLocation_textColor() {
let str = "Hello".withTextColor(.green)
- let subject = str.attribute(.textColor, at: 0, effectiveRange: nil)!.value as! UIColor
- let expected = str.attribute(NSForegroundColorAttributeName, at: 0, effectiveRange: nil) as! UIColor
+ let subject = str.attribute(.textColor, at: 0, effectiveRange: nil)!.value as! Color
+ let expected = str.attribute(NSForegroundColorAttributeName, at: 0, effectiveRange: nil) as! Color
XCTAssertEqual(subject, expected)
XCTAssertEqual(subject, .green)
}
@@ -173,20 +177,28 @@ class NSAttributedString_Tests: XCTestCase {
func testAttributeAtLocation_underlineColor() {
let str = "Hello".withUnderlineColor(.blue)
- let subject = str.attribute(.underlineColor, at: 0, effectiveRange: nil)!.value as! UIColor
- let expected = str.attribute(NSUnderlineColorAttributeName, at: 0, effectiveRange: nil) as! UIColor
+ let subject = str.attribute(.underlineColor, at: 0, effectiveRange: nil)!.value as! Color
+ let expected = str.attribute(NSUnderlineColorAttributeName, at: 0, effectiveRange: nil) as! Color
XCTAssertEqual(subject, expected)
XCTAssertEqual(subject, .blue)
}
func testAttributeAtLocation_underlineStyle() {
let str = "Hello".withUnderlineStyle(.byWord)
- let subject = str.attribute(.underlineStyle, at: 0, effectiveRange: nil)!.value as! NSUnderlineStyle
+ let subject = str.attribute(.underlineStyle, at: 0, effectiveRange: nil)!.value as! UnderlineStyle
let expected = str.attribute(NSUnderlineStyleAttributeName, at: 0, effectiveRange: nil) as! Int
XCTAssertEqual(subject.rawValue, expected)
XCTAssertEqual(subject, .byWord)
}
+ func testAttributeAtLocation_verticalGlyphForm() {
+ let str = "Hello".withVerticalGlyphForm(.horizontal)
+ let subject = str.attribute(.verticalGlyphForm, at: 0, effectiveRange: nil)!.value as! VerticalGlyphForm
+ let expected = str.attribute(NSVerticalGlyphFormAttributeName, at: 0, effectiveRange: nil) as! Int
+ XCTAssertEqual(subject.rawValue, expected)
+ XCTAssertEqual(subject, .horizontal)
+ }
+
func testAttributeAtLocation_writingDirections() {
let str = "Hello".withWritingDirections([.leftToRightOverride, .rightToLeftEmbedding])
let subject = str.attribute(.writingDirection, at: 0, effectiveRange: nil)!.value as! [WritingDirection]
@@ -207,7 +219,7 @@ class NSAttributedString_Tests: XCTestCase {
let str = "Hello".withUnderlineStyle(.patternDot) + "World".withUnderlineColor(.magenta)
var swiftyRange = NSRange()
var foundationRange = NSRange()
- let subject = str.attribute(.underlineStyle, at: 0, effectiveRange: &swiftyRange)!.value as! NSUnderlineStyle
+ let subject = str.attribute(.underlineStyle, at: 0, effectiveRange: &swiftyRange)!.value as! UnderlineStyle
let expected = str.attribute(NSUnderlineStyleAttributeName, at: 0, effectiveRange: &foundationRange) as! Int
XCTAssertEqual(subject.rawValue, expected)
XCTAssertEqual(subject, .patternDot)
@@ -231,4 +243,201 @@ class NSAttributedString_Tests: XCTestCase {
XCTAssertEqual(swiftyRange.location, 5)
}
+ #if os(macOS)
+
+ func testAttributeAtLocation_cursor() {
+ let cursor = Cursor(image: NSImage(), foregroundColorHint: .blue, backgroundColorHint: .red, hotSpot: NSPoint(x: 2, y: 2))
+ let str = "Hello".withCursor(cursor)
+ let subject = str.attribute(.cursor, at: 0, effectiveRange: nil)!.value as! Cursor
+ let expected = str.attribute(NSCursorAttributeName, at: 0, effectiveRange: nil) as! Cursor
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject, cursor)
+ }
+
+ func testAttributeAtLocation_markedClauseSegment() {
+ let str = "Hello".withMarkedClauseSegment(2)
+ let subject = str.attribute(.markedClauseSegment, at: 0, effectiveRange: nil)!.value as! Int
+ let expected = str.attribute(NSMarkedClauseSegmentAttributeName, at: 0, effectiveRange: nil) as! Int
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject, 2)
+ }
+
+ func testAttributeAtLocation_spellingState() {
+ let str = "Hello".withSpellingState(.grammarFlag)
+ let subject = str.attribute(.spellingState, at: 0, effectiveRange: nil)!.value as! SpellingState
+ let expected = str.attribute(NSSpellingStateAttributeName, at: 0, effectiveRange: nil) as! Int
+ XCTAssertEqual(subject.rawValue, expected)
+ XCTAssertEqual(subject, .grammarFlag)
+ }
+
+ func testAttributeAtLocation_superscript() {
+ let str = "Hello".withSuperscript(3)
+ let subject = str.attribute(.superscript, at: 0, effectiveRange: nil)!.value as! Int
+ let expected = str.attribute(NSSuperscriptAttributeName, at: 0, effectiveRange: nil) as! Int
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject, 3)
+ }
+
+ func testAttributeAtLocation_textAlternatives() {
+ let alternatives = TextAlternatives(primaryString: "Hi", alternativeStrings: ["Sup", "Yo"])
+ let str = "Hello".withTextAlternatives(alternatives)
+ let subject = str.attribute(.textAlternatives, at: 0, effectiveRange: nil)!.value as! TextAlternatives
+ let expected = str.attribute(NSTextAlternativesAttributeName, at: 0, effectiveRange: nil) as! TextAlternatives
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject, alternatives)
+ }
+
+ func testAttributeAtLocation_toolTip() {
+ let str = "Hello".withToolTip("Yo")
+ let subject = str.attribute(.toolTip, at: 0, effectiveRange: nil)!.value as! String
+ let expected = str.attribute(NSToolTipAttributeName, at: 0, effectiveRange: nil) as! String
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject, "Yo")
+ }
+
+ // MARK: - Font Attributes
+
+ func testFontAttributes_onlyFontAttributes() {
+ let subject = "Hello".withFont(.systemFont(ofSize: 19)).fontAttributes(in: 0 ..< 3).foundationAttributes
+ let expected = NSAttributedString(string: "Hello", attributes: [NSFontAttributeName: Font.systemFont(ofSize: 19)]).fontAttributes(in: NSRange(location: 0, length: 3))
+ XCTAssertEqual(subject as NSDictionary, expected as NSDictionary)
+ XCTAssertEqual(subject.swiftyAttributes, [.font(.systemFont(ofSize: 19))])
+ }
+
+ func testFontAttributes_includesNonFontAttributes() {
+ let url = URL(string: "www.google.com")!
+ let subject = "Hello".withAttributes([.font(.systemFont(ofSize: 19)), .link(url)]).fontAttributes(in: 0 ..< 3).foundationAttributes
+ let expected = NSAttributedString(string: "Hello", attributes: [NSFontAttributeName: Font.systemFont(ofSize: 19), NSLinkAttributeName: url]).fontAttributes(in: NSRange(location: 0, length: 3))
+ XCTAssertEqual(subject as NSDictionary, expected as NSDictionary)
+ XCTAssertEqual(subject.swiftyAttributes, [.font(.systemFont(ofSize: 19))])
+ }
+
+ // MARK: - Ruler Attributes
+
+ func testRulerAttributes_onlyRulerAttributes() {
+ let style = NSMutableParagraphStyle()
+ style.alignment = .center
+ let subject = "Hello".withParagraphStyle(style).rulerAttributes(in: 1 ..< 3).foundationAttributes
+ let expected = NSAttributedString(string: "Hello", attributes: [NSParagraphStyleAttributeName: style]).rulerAttributes(in: NSRange(location: 1, length: 2))
+ XCTAssertEqual(subject as NSDictionary, expected as NSDictionary)
+ XCTAssertEqual(subject.swiftyAttributes, [.paragraphStyle(style)])
+ }
+
+ func testRulerAttributes_includesNonRulerAttributes() {
+ let style = NSMutableParagraphStyle()
+ style.alignment = .center
+ let subject = "Hello".withAttributes([.paragraphStyle(style), .textColor(.cyan)]).rulerAttributes(in: 1 ..< 3).foundationAttributes
+ let expected = NSAttributedString(string: "Hello", attributes: [NSParagraphStyleAttributeName: style, NSForegroundColorAttributeName: Color.cyan]).rulerAttributes(in: NSRange(location: 1, length: 2))
+ XCTAssertEqual(subject as NSDictionary, expected as NSDictionary)
+ XCTAssertEqual(subject.swiftyAttributes, [.paragraphStyle(style)])
+ }
+
+ #endif
+
+ // MARK: Enumeration
+
+ func testEnumerateSingleAttribute() {
+ let str = "Hello".withExpansion(3) + "World".attributedString
+ var enumerated = false
+ str.enumerateAttribute(.expansion, in: 0 ..< 7) { value, range, _ in
+ enumerated = true
+ if range.upperBound == 5 {
+ XCTAssertEqual(value as! Double, 3)
+ XCTAssertEqual(range, 0 ..< 5)
+ } else {
+ XCTAssertNil(value)
+ XCTAssertEqual(range, 5 ..< 7)
+ }
+ }
+ XCTAssertTrue(enumerated)
+ }
+
+ func testEnumerateMultipleAttributes() {
+ var attrs: [Attribute] = [.backgroundColor(.red), .baselineOffset(2), .obliqueness(3)]
+ let str = "Hello World! How is everyone?".attributedString
+ str.addAttributes(attrs, range: 0 ..< 7)
+ attrs[2] = .obliqueness(2)
+ str.addAttributes(attrs, range: 7 ..< 12)
+ str.addAttributes(attrs + [.kern(4)], range: 12 ..< 17)
+
+ let sort: (Attribute, Attribute) -> Bool = { $0.0.keyName < $0.1.keyName }
+
+ var enumerated = false
+ str.enumerateAttributes(in: 3 ..< 15) { attrs, range, _ in
+ enumerated = true
+
+ switch range.upperBound {
+ case 7:
+ XCTAssertEqual(attrs.sorted(by: sort), [.backgroundColor(.red), .baselineOffset(2), .obliqueness(3)])
+ XCTAssertEqual(range, 3 ..< 7)
+ case 12:
+ XCTAssertEqual(attrs.sorted(by: sort), [.backgroundColor(.red), .baselineOffset(2), .obliqueness(2)])
+ XCTAssertEqual(range, 7 ..< 12)
+ case 15:
+ XCTAssertEqual(attrs.sorted(by: sort), [.backgroundColor(.red), .baselineOffset(2), .kern(4), .obliqueness(2)])
+ XCTAssertEqual(range, 12 ..< 15)
+ default:
+ XCTFail("Incorrect upper bound when enumerating attributes")
+ }
+ }
+
+ XCTAssertTrue(enumerated)
+ }
+
+ func testEnumerate_stopValue() {
+ let str = "Hello".withBackgroundColor(.blue) + "World".withKern(3) + "!".withTextColor(.magenta)
+ var enumerations = 0
+ str.enumerateAttributes(in: 0 ..< str.length) { _ in
+ enumerations += 1
+ }
+ XCTAssertEqual(enumerations, 3)
+ enumerations = 0
+ str.enumerateAttributes(in: 0 ..< str.length) { _, _, stop in
+ enumerations += 1
+ if enumerations == 2 {
+ stop.pointee = ObjCBool(true)
+ }
+ }
+ XCTAssertEqual(enumerations, 2)
+ }
+
+ func testEnumerate_options() {
+ let str = "Hello".withExpansion(3) + "World".attributedString
+ var enumeratedEnding = false
+ str.enumerateAttribute(.expansion, in: 0 ..< 7, options: .reverse) { value, range, _ in
+ if range.upperBound == 7 {
+ enumeratedEnding = true
+ XCTAssertNil(value)
+ } else {
+ XCTAssertTrue(enumeratedEnding)
+ XCTAssertEqual(value as! Double, 3)
+ }
+ }
+ }
+
+ func testEnumerate_returnsArrayOfTuples() {
+ var attrs: [Attribute] = [.backgroundColor(.red), .obliqueness(3)]
+ let str = "Hello World! How is everyone?".attributedString
+ str.addAttributes(attrs, range: 0 ..< 7)
+ attrs[1] = .obliqueness(2)
+ str.addAttributes(attrs, range: 7 ..< 12)
+ str.addAttributes(attrs + [.kern(4)], range: 12 ..< 17)
+
+ let sort: (Attribute, Attribute) -> Bool = { $0.0.keyName < $0.1.keyName }
+
+ let subject = str.attributes(in: 3 ..< 15)
+ let expected: [([Attribute], Range)] = [
+ ([.backgroundColor(.red), .obliqueness(3)], 3 ..< 7),
+ ([.backgroundColor(.red), .obliqueness(2)], 7 ..< 12),
+ ([.backgroundColor(.red), .kern(4), .obliqueness(2)], 12 ..< 15)
+ ]
+
+ XCTAssertEqual(subject.count, 3)
+
+ for (index, tuple) in subject.enumerated() {
+ XCTAssertEqual(tuple.0.sorted(by: sort), expected[index].0.sorted(by: sort))
+ XCTAssertEqual(tuple.1, expected[index].1)
+ }
+ }
+
}
diff --git a/SwiftyAttributesTests/NSMutableAttributedString_Tests.swift b/SwiftyAttributesTests/NSMutableAttributedString_Tests.swift
index cbbffaf..f91f877 100644
--- a/SwiftyAttributesTests/NSMutableAttributedString_Tests.swift
+++ b/SwiftyAttributesTests/NSMutableAttributedString_Tests.swift
@@ -27,7 +27,7 @@ class NSMutableAttributedString_Tests: XCTestCase {
XCTAssertEqual(subject, expected)
subject.addAttributes([.font(.boldSystemFont(ofSize: 17))], range: NSRange(location: 0, length: 1))
XCTAssertNotEqual(subject, expected)
- expected.addAttributes([NSFontAttributeName: UIFont.boldSystemFont(ofSize: 17)], range: NSRange(location: 0, length: 1))
+ expected.addAttributes([NSFontAttributeName: Font.boldSystemFont(ofSize: 17)], range: NSRange(location: 0, length: 1))
XCTAssertEqual(subject, expected)
}
@@ -37,7 +37,7 @@ class NSMutableAttributedString_Tests: XCTestCase {
XCTAssertEqual(subject, expected)
subject.setAttributes([.backgroundColor(.orange)], range: 0 ..< 3)
XCTAssertNotEqual(subject, expected)
- expected.setAttributes([NSBackgroundColorAttributeName: UIColor.orange], range: NSRange(location: 0, length: 3))
+ expected.setAttributes([NSBackgroundColorAttributeName: Color.orange], range: NSRange(location: 0, length: 3))
XCTAssertEqual(subject, expected)
}
@@ -47,7 +47,7 @@ class NSMutableAttributedString_Tests: XCTestCase {
XCTAssertEqual(subject, expected)
subject.setAttributes([.backgroundColor(.orange)], range: NSRange(location: 2, length: 2))
XCTAssertNotEqual(subject, expected)
- expected.setAttributes([NSBackgroundColorAttributeName: UIColor.orange], range: NSRange(location: 2, length: 2))
+ expected.setAttributes([NSBackgroundColorAttributeName: Color.orange], range: NSRange(location: 2, length: 2))
XCTAssertEqual(subject, expected)
}
@@ -67,7 +67,7 @@ class NSMutableAttributedString_Tests: XCTestCase {
XCTAssertEqual(subject, expected)
subject.replaceCharacters(in: 0 ..< 2, with: "Chi".withBackgroundColor(.magenta))
XCTAssertNotEqual(subject, expected)
- expected.replaceCharacters(in: NSRange(location: 0, length: 2), with: NSAttributedString(string: "Chi", attributes: [NSBackgroundColorAttributeName: UIColor.magenta]))
+ expected.replaceCharacters(in: NSRange(location: 0, length: 2), with: NSAttributedString(string: "Chi", attributes: [NSBackgroundColorAttributeName: Color.magenta]))
XCTAssertEqual(subject, expected)
}
diff --git a/SwiftyAttributesTests/Operators_Tests.swift b/SwiftyAttributesTests/Operators_Tests.swift
index 8bee293..c85a913 100644
--- a/SwiftyAttributesTests/Operators_Tests.swift
+++ b/SwiftyAttributesTests/Operators_Tests.swift
@@ -15,11 +15,11 @@ class Operators_Tests: XCTestCase {
let lhs = "Hello".withFont(.systemFont(ofSize: 19))
let rhs = "World".withTextColor(.magenta).withBackgroundColor(.orange).withFont(.boldSystemFont(ofSize: 24))
let newString = lhs + rhs
- let leftAttributes = [NSFontAttributeName: UIFont.systemFont(ofSize: 19)] as [String: NSObject]
+ let leftAttributes = [NSFontAttributeName: Font.systemFont(ofSize: 19)] as [String: NSObject]
XCTAssertEqual(newString.attributes(at: 0, effectiveRange: nil) as! [String: NSObject], leftAttributes)
- let rightAttributes = [NSForegroundColorAttributeName: UIColor.magenta,
- NSBackgroundColorAttributeName: UIColor.orange,
- NSFontAttributeName: UIFont.boldSystemFont(ofSize: 24)] as [String: NSObject]
+ let rightAttributes = [NSForegroundColorAttributeName: Color.magenta,
+ NSBackgroundColorAttributeName: Color.orange,
+ NSFontAttributeName: Font.boldSystemFont(ofSize: 24)] as [String: NSObject]
XCTAssertEqual(newString.attributes(at: lhs.length + 1, effectiveRange: nil) as! [String: NSObject], rightAttributes)
}
diff --git a/SwiftyAttributesTests/SpellingState_Tests.swift b/SwiftyAttributesTests/SpellingState_Tests.swift
new file mode 100644
index 0000000..2586b67
--- /dev/null
+++ b/SwiftyAttributesTests/SpellingState_Tests.swift
@@ -0,0 +1,32 @@
+//
+// SpellingState_Tests.swift
+// SwiftyAttributes
+//
+// Created by Eddie Kaiger on 11/26/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+#if os(macOS)
+import XCTest
+import SwiftyAttributes
+
+class SpellingState_Tests: XCTestCase {
+
+ func testInit_nil() {
+ XCTAssertNil(SpellingState(rawValue: 6))
+ }
+
+ func testInit_flags() {
+ XCTAssertEqual(SpellingState(rawValue: NSSpellingStateGrammarFlag)!, .grammarFlag)
+ XCTAssertEqual(SpellingState(rawValue: NSSpellingStateSpellingFlag)!, .spellingFlag)
+ XCTAssertEqual(SpellingState(rawValue: 0)!, .none)
+ }
+
+ func testRawValue() {
+ XCTAssertEqual(SpellingState.grammarFlag.rawValue, NSSpellingStateGrammarFlag)
+ XCTAssertEqual(SpellingState.spellingFlag.rawValue, NSSpellingStateSpellingFlag)
+ XCTAssertEqual(SpellingState.none.rawValue, 0)
+ }
+
+}
+#endif
diff --git a/SwiftyAttributesTests/SwiftyAttributes_Tests.swift b/SwiftyAttributesTests/SwiftyAttributes_Tests.swift
index 41d4ccf..8d36c45 100644
--- a/SwiftyAttributesTests/SwiftyAttributes_Tests.swift
+++ b/SwiftyAttributesTests/SwiftyAttributes_Tests.swift
@@ -18,9 +18,12 @@ class SwiftyAttributesTests: XCTestCase {
}
func testAttribute_font() {
- let subject = "Hello".withFont(UIFont.boldSystemFont(ofSize: 26))
- let expected = NSAttributedString(string: "Hello", attributes: [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 26)])
+ let font = Font.boldSystemFont(ofSize: 26)
+ let subject = "Hello".withFont(font)
+ let subject2 = "Hello".attributedString.withFont(font)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSFontAttributeName: Font.boldSystemFont(ofSize: 26)])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_paragraphStyle() {
@@ -28,137 +31,255 @@ class SwiftyAttributesTests: XCTestCase {
style.lineSpacing = 4
style.lineBreakMode = .byTruncatingMiddle
let subject = "Hello".withParagraphStyle(style)
+ let subject2 = "Hello".attributedString.withParagraphStyle(style)
let expected = NSAttributedString(string: "Hello", attributes: [NSParagraphStyleAttributeName: style])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_textColor() {
let subject = "Hello".withTextColor(.magenta)
- let expected = NSAttributedString(string: "Hello", attributes: [NSForegroundColorAttributeName: UIColor.magenta])
+ let subject2 = "Hello".attributedString.withTextColor(.magenta)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSForegroundColorAttributeName: Color.magenta])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_backgroundColor() {
let subject = "Hello".withBackgroundColor(.cyan)
- let expected = NSAttributedString(string: "Hello", attributes: [NSBackgroundColorAttributeName: UIColor.cyan])
+ let subject2 = "Hello".attributedString.withBackgroundColor(.cyan)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSBackgroundColorAttributeName: Color.cyan])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_ligature() {
let subject = "Hello".withLigatures(.none)
+ let subject2 = "Hello".attributedString.withLigatures(.none)
let expected = NSAttributedString(string: "Hello", attributes: [NSLigatureAttributeName: NSNumber(value: Ligatures.none.rawValue)])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_kern() {
let subject = "Hello".withKern(12)
+ let subject2 = "Hello".attributedString.withKern(12)
let expected = NSAttributedString(string: "Hello", attributes: [NSKernAttributeName: NSNumber(value: 12)])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_strikethroughStyle() {
let subject = "Hello".withStrikethroughStyle(.patternDashDot)
- let expected = NSAttributedString(string: "Hello", attributes: [NSStrikethroughStyleAttributeName: NSNumber(value: NSUnderlineStyle.patternDashDot.rawValue)])
+ let subject2 = "Hello".attributedString.withStrikethroughStyle(.patternDashDot)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSStrikethroughStyleAttributeName: NSNumber(value: UnderlineStyle.patternDashDot.rawValue)])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_underlineStyle() {
let subject = "Hello".withUnderlineStyle(.styleDouble)
- let expected = NSAttributedString(string: "Hello", attributes: [NSUnderlineStyleAttributeName: NSNumber(value: NSUnderlineStyle.styleDouble.rawValue)])
+ let subject2 = "Hello".attributedString.withUnderlineStyle(.styleDouble)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSUnderlineStyleAttributeName: NSNumber(value: UnderlineStyle.styleDouble.rawValue)])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_strokeColor() {
let subject = "Hello".withStrokeColor(.orange)
- let expected = NSAttributedString(string: "Hello", attributes: [NSStrokeColorAttributeName: UIColor.orange])
+ let subject2 = "Hello".attributedString.withStrokeColor(.orange)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSStrokeColorAttributeName: Color.orange])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_strokeWidth() {
let subject = "Hello".withStrokeWidth(3.2)
+ let subject2 = "Hello".attributedString.withStrokeWidth(3.2)
let expected = NSAttributedString(string: "Hello", attributes: [NSStrokeWidthAttributeName: NSNumber(value: 3.2)])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_shadow() {
- let shadow = NSShadow()
+ let shadow = Shadow()
shadow.shadowBlurRadius = 4
- shadow.shadowColor = UIColor.brown
+ shadow.shadowColor = Color.brown
let subject = "Hello".withShadow(shadow)
+ let subject2 = "Hello".attributedString.withShadow(shadow)
let expected = NSAttributedString(string: "Hello", attributes: [NSShadowAttributeName: shadow])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_textEffect() {
let subject = "Hello".withTextEffect(.letterPressStyle)
+ let subject2 = "Hello".attributedString.withTextEffect(.letterPressStyle)
let expected = NSAttributedString(string: "Hello", attributes: [NSTextEffectAttributeName: NSTextEffectLetterpressStyle])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_attachment() {
- let attachment = NSTextAttachment(data: nil, ofType: nil)
+ let attachment = TextAttachment(data: nil, ofType: nil)
let subject = "Hello".withAttachment(attachment)
+ let subject2 = "Hello".attributedString.withAttachment(attachment)
let expected = NSAttributedString(string: "Hello", attributes: [NSAttachmentAttributeName: attachment])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_link() {
let url = URL(string: "https://google.com")!
let subject = "Hello".withLink(url)
+ let subject2 = "Hello".attributedString.withLink(url)
let expected = NSAttributedString(string: "Hello", attributes: [NSLinkAttributeName: url])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_baselineOffset() {
let subject = "Hello".withBaselineOffset(5)
+ let subject2 = "Hello".attributedString.withBaselineOffset(5)
let expected = NSAttributedString(string: "Hello", attributes: [NSBaselineOffsetAttributeName: NSNumber(value: 5)])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_underlineColor() {
let subject = "Hello".withUnderlineColor(.magenta)
- let expected = NSAttributedString(string: "Hello", attributes: [NSUnderlineColorAttributeName: UIColor.magenta])
+ let subject2 = "Hello".attributedString.withUnderlineColor(.magenta)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSUnderlineColorAttributeName: Color.magenta])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_strikethroughColor() {
let subject = "Hello".withStrikethroughColor(.brown)
- let expected = NSAttributedString(string: "Hello", attributes: [NSStrikethroughColorAttributeName: UIColor.brown])
+ let subject2 = "Hello".attributedString.withStrikethroughColor(.brown)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSStrikethroughColorAttributeName: Color.brown])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_obliqueness() {
let subject = "Hello".withObliqueness(4.5)
+ let subject2 = "Hello".attributedString.withObliqueness(4.5)
let expected = NSAttributedString(string: "Hello", attributes: [NSObliquenessAttributeName: NSNumber(value: 4.5)])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
func testAttribute_expansion() {
let subject = "Hello".withExpansion(7)
+ let subject2 = "Hello".attributedString.withExpansion(7)
let expected = NSAttributedString(string: "Hello", attributes: [NSExpansionAttributeName: NSNumber(value: 7)])
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
+ func testAttribute_verticalGlyphForm() {
+ let subject = "Hello".withVerticalGlyphForm(.horizontal)
+ let subject2 = "Hello".attributedString.withVerticalGlyphForm(.horizontal)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSVerticalGlyphFormAttributeName: NSNumber(value: 0)])
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
+ }
+
+ @available(iOS 9.0, *)
+ func testAttribute_writingDirection() {
+ let subject = "Hello".withWritingDirections([.rightToLeftOverride])
+ let subject2 = "Hello".attributedString.withWritingDirections([.rightToLeftOverride])
+ let expected = NSAttributedString(string: "Hello", attributes: [NSWritingDirectionAttributeName: [NSNumber(value: NSWritingDirection.rightToLeft.rawValue | NSWritingDirectionFormatType.override.rawValue)]])
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
+ }
+
+ #if os(macOS)
+
+ func testAttribute_cursor() {
+ let cursor = Cursor(image: NSImage(), foregroundColorHint: .blue, backgroundColorHint: .red, hotSpot: NSPoint(x: 2, y: 2))
+ let subject = "Hello".withCursor(cursor)
+ let subject2 = "Hello".attributedString.withCursor(cursor)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSCursorAttributeName: cursor])
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
+ }
+
+ func testAttribute_markedClauseSegment() {
+ let subject = "Hello".withMarkedClauseSegment(3)
+ let subject2 = "Hello".attributedString.withMarkedClauseSegment(3)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSMarkedClauseSegmentAttributeName: 3])
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
+ }
+
+ func testAttribute_spellingState_grammar() {
+ let subject = "Hello".withSpellingState(.grammarFlag)
+ let subject2 = "Hello".attributedString.withSpellingState(.grammarFlag)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSSpellingStateAttributeName: NSSpellingStateGrammarFlag])
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
+ }
+
+ func testAttribute_spellingState_none() {
+ let subject = "Hello".withSpellingState(.none)
+ let subject2 = "Hello".attributedString.withSpellingState(.none)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSSpellingStateAttributeName: 0])
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
+ }
+
+ func testAttribute_superscript() {
+ let subject = "Hello".withSuperscript(4)
+ let subject2 = "Hello".attributedString.withSuperscript(4)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSSuperscriptAttributeName: 4])
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
+ }
+
+ func testAttribute_textAlternatives() {
+ let alternatives = TextAlternatives(primaryString: "Hi", alternativeStrings: ["Yo", "Sup"])
+ let subject = "Hello".withTextAlternatives(alternatives)
+ let subject2 = "Hello".attributedString.withTextAlternatives(alternatives)
+ let expected = NSAttributedString(string: "Hello", attributes: [NSTextAlternativesAttributeName: alternatives])
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
+ }
+
+ func testAttribute_toolTip() {
+ let subject = "Hello".withToolTip("Sah dude")
+ let subject2 = "Hello".attributedString.withToolTip("Sah dude")
+ let expected = NSAttributedString(string: "Hello", attributes: [NSToolTipAttributeName: "Sah dude"])
+ XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
+ }
+
+ #endif
+
func testMultipleAttributes_withSyntax() {
let subject = "Hello".withTextColor(.darkGray).withBackgroundColor(.magenta).withStrikethroughStyle(.patternDashDotDot)
let attrs: [String: Any] = [
- NSForegroundColorAttributeName: UIColor.darkGray,
- NSBackgroundColorAttributeName: UIColor.magenta,
- NSStrikethroughStyleAttributeName: NSUnderlineStyle.patternDashDotDot.rawValue
+ NSForegroundColorAttributeName: Color.darkGray,
+ NSBackgroundColorAttributeName: Color.magenta,
+ NSStrikethroughStyleAttributeName: UnderlineStyle.patternDashDotDot.rawValue
]
let expected = NSAttributedString(string: "Hello", attributes: attrs)
XCTAssertEqual(subject, expected)
}
func testMultipleAttributes_arraySyntax() {
- let subject = "Hello".withAttributes([.font(.boldSystemFont(ofSize: 19)), .link(URL(string: "https://google.com")!), .underlineStyle(.patternSolid)])
+ let attributes: [Attribute] = [.font(.boldSystemFont(ofSize: 19)), .link(URL(string: "https://google.com")!), .underlineStyle(.patternSolid)]
+ let subject = "Hello".withAttributes(attributes)
+ let subject2 = "Hello".attributedString.withAttributes(attributes)
let attrs: [String: Any] = [
- NSFontAttributeName: UIFont.boldSystemFont(ofSize: 19),
+ NSFontAttributeName: Font.boldSystemFont(ofSize: 19),
NSLinkAttributeName: URL(string: "https://google.com")!,
- NSUnderlineStyleAttributeName: NSUnderlineStyle.patternSolid.rawValue
+ NSUnderlineStyleAttributeName: UnderlineStyle.patternSolid.rawValue
]
let expected = NSAttributedString(string: "Hello", attributes: attrs)
XCTAssertEqual(subject, expected)
+ XCTAssertEqual(subject2, expected)
}
}
diff --git a/SwiftyAttributesTests/VerticalGlyphForm_Tests.swift b/SwiftyAttributesTests/VerticalGlyphForm_Tests.swift
new file mode 100644
index 0000000..b04eb41
--- /dev/null
+++ b/SwiftyAttributesTests/VerticalGlyphForm_Tests.swift
@@ -0,0 +1,21 @@
+//
+// VerticalGlyphForm_Tests.swift
+// SwiftyAttributes
+//
+// Created by Eddie Kaiger on 11/29/16.
+// Copyright © 2016 Eddie Kaiger. All rights reserved.
+//
+
+import XCTest
+import SwiftyAttributes
+
+class VerticalGlyphForm_Tests: XCTestCase {
+
+ func testRawValue() {
+ XCTAssertEqual(VerticalGlyphForm.horizontal.rawValue, 0)
+ #if os(macOS)
+ XCTAssertEqual(VerticalGlyphForm.vertical.rawValue, 1)
+ #endif
+ }
+
+}
diff --git a/codecov.yml b/codecov.yml
index 5413feb..0da9ac5 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -7,14 +7,16 @@ comment:
require_changes: false
coverage:
precision: 2
- range:
- - 70.0
- - 99.0
+ range: "70...99"
round: down
status:
changes: false
- patch: true
- project: true
+ patch:
+ default:
+ target: 99
+ project:
+ default:
+ target: 99
parsers:
gcov:
branch_detection: