├── .gitignore ├── .swiftlint.yml ├── Cartfile ├── Cartfile.resolved ├── Carthage └── Checkouts │ ├── CommandLine │ ├── .gitignore │ ├── .travis.yml │ ├── Carthage │ │ └── Build │ ├── CommandLineKit.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── CommandLine.xcscheme │ ├── CommandLineKit │ │ ├── CommandLine.swift │ │ ├── Info.plist │ │ ├── Option.swift │ │ └── StringExtensions.swift │ ├── LICENSE │ ├── Package.swift │ ├── README.md │ ├── Tests │ │ ├── CommandLineKitTests │ │ │ ├── CommandLineTests.swift │ │ │ ├── Info.plist │ │ │ └── StringExtensionTests.swift │ │ └── LinuxMain.swift │ └── script │ │ └── test │ └── SwiftyJSON │ ├── .gitignore │ ├── .travis.yml │ ├── CHANGELOG.md │ ├── Example │ ├── Example.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── Example │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ ├── Contents.json │ │ │ └── Default@2x.png │ │ ├── Info.plist │ │ ├── SwiftyJSONTests.json │ │ └── ViewController.swift │ ├── LICENSE │ ├── README.md │ ├── Source │ ├── Info-OSX.plist │ ├── Info-iOS.plist │ ├── Info-tvOS.plist │ ├── Info-watchOS.plist │ ├── SwiftyJSON.h │ └── SwiftyJSON.swift │ ├── SwiftyJSON.podspec │ ├── SwiftyJSON.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── SwiftyJSON OSX.xcscheme │ ├── SwiftyJSON.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── WorkspaceSettings.xcsettings │ └── Tests │ ├── ArrayTests.swift │ ├── BaseTests.swift │ ├── ComparableTests.swift │ ├── DictionaryTests.swift │ ├── Info-OSX.plist │ ├── Info-iOS.plist │ ├── Info-tvOS.plist │ ├── LiteralConvertibleTests.swift │ ├── NumberTests.swift │ ├── PerformanceTests.swift │ ├── PrintableTests.swift │ ├── RawRepresentableTests.swift │ ├── RawTests.swift │ ├── SequenceTypeTests.swift │ ├── StringTests.swift │ ├── SubscriptTests.swift │ └── Tests.json ├── Excerptor.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── Excerptor.xcscheme │ ├── Install Excerptor Into Applications Folder.xcscheme │ ├── Install SIMBL Plugin PDFReaderPlugin.xcscheme │ └── PDFReaderPlugin.xcscheme ├── Excerptor ├── Annotation.swift ├── AnnotationLink.swift ├── AppDelegate.swift ├── FileTemplate.swift ├── Helpers │ ├── FileID.swift │ ├── PasteboardHelper.swift │ ├── delay-helper.swift │ ├── error-helper.swift │ ├── nscolor-helper.swift │ ├── nsdate-helper.swift │ └── string-helper.swift ├── Link.swift ├── Preferences.swift ├── PreferencesDefaultValues(DNtp).plist ├── PreferencesDefaultValues.plist ├── PreferencesWindow.xib ├── PreferencesWindowController.swift ├── Selection.swift ├── SelectionLink.swift ├── ServicesProvider.swift ├── Supporting Files │ ├── Base.lproj │ │ └── MainMenu.xib │ ├── DEVONthinkPro.swift │ ├── Excerptor-Bridging-Header.h │ ├── Info.plist │ └── NSUserNotification-Private.h ├── global-functions.swift └── main.swift ├── Frameworks └── SkimNotes.framework │ ├── Headers │ ├── NSFileManager_SKNExtensions.h │ ├── PDFAnnotation_SKNExtensions.h │ ├── PDFDocument_SKNExtensions.h │ ├── SKNExtendedAttributeManager.h │ ├── SKNPDFAnnotationNote.h │ └── SkimNotes.h │ ├── Resources │ ├── Dutch.lproj │ │ └── SkimNotes.strings │ ├── English.lproj │ │ └── SkimNotes.strings │ ├── French.lproj │ │ └── SkimNotes.strings │ ├── German.lproj │ │ └── SkimNotes.strings │ ├── Info.plist │ ├── Italian.lproj │ │ └── SkimNotes.strings │ ├── Japanese.lproj │ │ └── SkimNotes.strings │ ├── Spanish.lproj │ │ └── SkimNotes.strings │ ├── pl.lproj │ │ └── SkimNotes.strings │ ├── ru.lproj │ │ └── SkimNotes.strings │ ├── zh_CN.lproj │ │ └── SkimNotes.strings │ └── zh_TW.lproj │ │ └── SkimNotes.strings │ ├── SkimNotes │ └── Versions │ ├── A │ ├── Headers │ │ ├── NSFileManager_SKNExtensions.h │ │ ├── PDFAnnotation_SKNExtensions.h │ │ ├── PDFDocument_SKNExtensions.h │ │ ├── SKNExtendedAttributeManager.h │ │ ├── SKNPDFAnnotationNote.h │ │ └── SkimNotes.h │ ├── Resources │ │ ├── Dutch.lproj │ │ │ └── SkimNotes.strings │ │ ├── English.lproj │ │ │ └── SkimNotes.strings │ │ ├── French.lproj │ │ │ └── SkimNotes.strings │ │ ├── German.lproj │ │ │ └── SkimNotes.strings │ │ ├── Info.plist │ │ ├── Italian.lproj │ │ │ └── SkimNotes.strings │ │ ├── Japanese.lproj │ │ │ └── SkimNotes.strings │ │ ├── Spanish.lproj │ │ │ └── SkimNotes.strings │ │ ├── pl.lproj │ │ │ └── SkimNotes.strings │ │ ├── ru.lproj │ │ │ └── SkimNotes.strings │ │ ├── zh_CN.lproj │ │ │ └── SkimNotes.strings │ │ └── zh_TW.lproj │ │ │ └── SkimNotes.strings │ └── SkimNotes │ └── Current │ ├── Headers │ ├── NSFileManager_SKNExtensions.h │ ├── PDFAnnotation_SKNExtensions.h │ ├── PDFDocument_SKNExtensions.h │ ├── SKNExtendedAttributeManager.h │ ├── SKNPDFAnnotationNote.h │ └── SkimNotes.h │ ├── Resources │ ├── Dutch.lproj │ │ └── SkimNotes.strings │ ├── English.lproj │ │ └── SkimNotes.strings │ ├── French.lproj │ │ └── SkimNotes.strings │ ├── German.lproj │ │ └── SkimNotes.strings │ ├── Info.plist │ ├── Italian.lproj │ │ └── SkimNotes.strings │ ├── Japanese.lproj │ │ └── SkimNotes.strings │ ├── Spanish.lproj │ │ └── SkimNotes.strings │ ├── pl.lproj │ │ └── SkimNotes.strings │ ├── ru.lproj │ │ └── SkimNotes.strings │ ├── zh_CN.lproj │ │ └── SkimNotes.strings │ └── zh_TW.lproj │ │ └── SkimNotes.strings │ └── SkimNotes ├── LICENSE ├── PDFKit Extensions ├── CGPoint.swift ├── PDFAnnotation.swift ├── PDFAnnotationMarkup.swift ├── PDFDocument.swift └── PDFPage.swift ├── PDFReaderPlugin ├── Helpers │ ├── NSArray+Map.h │ ├── NSArray+Map.m │ ├── PDFSelection+BoundsDescription.h │ ├── PDFSelection+BoundsDescription.m │ ├── PasteboardHelper.h │ └── PasteboardHelper.m ├── PDFReaderPlugin.h ├── PDFReaderPlugin.m └── Supporting Files │ └── Info.plist ├── PopClipExtension ├── Config.plist ├── Makefile └── excerptor.popclipextz ├── PrefsPane ├── Base.lproj │ └── PrefsPane.xib ├── HelpWindowController.h ├── HelpWindowController.m ├── HelpWindowController.xib ├── PrefsPane.h ├── PrefsPane.m ├── PrefsPane.tiff ├── PrefsPaneDelegate.h └── Supporting Files │ └── Info.plist ├── README.md ├── Shared Files ├── AnnotationLocation.h ├── AnnotationLocation.m ├── Location.h ├── Location.m ├── Preview.h ├── SelectionLineLocation.h ├── SelectionLineLocation.m ├── SelectionLocation.h ├── SelectionLocation.m └── Skim.h └── screenshots ├── excerpt_to_pasteboard.gif ├── mmd_quicklook.png ├── preferences_excerpt_to_file.png └── preferences_excerpt_to_pasteboard.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | .idea 21 | 22 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: # rule identifiers to exclude from running 2 | - variable_name_max_length 3 | - line_length 4 | excluded: # paths to ignore during linting. overridden by `included`. 5 | - Excerptor/Supporting Files/DEVONthinkPro.swift 6 | - Cartfile 7 | - Cartfile.resolved 8 | - Carthage 9 | - Excerptor.xcodeproj 10 | - Frameworks 11 | - LICENSE 12 | - PDFReaderPlugin 13 | - PopClipExtension 14 | - PrefsPane 15 | - Shared Files 16 | - screenshots 17 | # parameterized rules are first parameterized as a warning level, then error level. 18 | type_body_length: 19 | - 300 # warning 20 | - 400 # error 21 | # parameterized rules are first parameterized as a warning level, then error level. 22 | variable_name_min_length: 23 | - 3 # warning 24 | - 2 # error 25 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "guoc/CommandLine" "3f0e41c8db45cf2fd447e335db9f0af9d2eda106" 2 | 3 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "guoc/CommandLine" "3f0e41c8db45cf2fd447e335db9f0af9d2eda106" 2 | -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | .build/ 5 | .build-linux 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | *.moved-aside 17 | DerivedData 18 | *.hmap 19 | *.ipa 20 | *.xcuserstate 21 | .DS_Store 22 | 23 | -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/.travis.yml: -------------------------------------------------------------------------------- 1 | matrix: 2 | include: 3 | - os: osx 4 | language: objective-c # this is a lie 5 | xcode_project: CommandLine.xcodeproj 6 | xcode_scheme: CommandLine 7 | script: xcodebuild -scheme CommandLine test 8 | osx_image: xcode8.2 9 | - os: linux 10 | dist: trusty 11 | sudo: false 12 | services: docker 13 | before_install: 14 | - docker pull swiftdocker/swift:latest 15 | script: 16 | - docker run -v "$(pwd):/src" swiftdocker/swift:latest /src/script/test 17 | -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/Carthage/Build: -------------------------------------------------------------------------------- 1 | ../../../../Carthage/Build -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/CommandLineKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/CommandLineKit.xcodeproj/xcshareddata/xcschemes/CommandLine.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 45 | 46 | 48 | 54 | 55 | 56 | 57 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 79 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 98 | 104 | 105 | 106 | 107 | 109 | 110 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/CommandLineKit/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSHumanReadableCopyright 24 | Copyright © 2014 Ben Gollmer. Licensed under the Apache License, Version 2.0. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/CommandLineKit/StringExtensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * StringExtensions.swift 3 | * Copyright (c) 2014 Ben Gollmer. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /* Required for localeconv(3) */ 19 | #if os(OSX) 20 | import Darwin 21 | #elseif os(Linux) 22 | import Glibc 23 | #endif 24 | 25 | internal extension String { 26 | /* Retrieves locale-specified decimal separator from the environment 27 | * using localeconv(3). 28 | */ 29 | private func _localDecimalPoint() -> Character { 30 | guard let locale = localeconv(), let decimalPoint = locale.pointee.decimal_point else { 31 | return "." 32 | } 33 | 34 | return Character(UnicodeScalar(UInt8(bitPattern: decimalPoint.pointee))) 35 | } 36 | 37 | /** 38 | * Attempts to parse the string value into a Double. 39 | * 40 | * - returns: A Double if the string can be parsed, nil otherwise. 41 | */ 42 | func toDouble() -> Double? { 43 | let decimalPoint = String(self._localDecimalPoint()) 44 | guard decimalPoint == "." || self.range(of: ".") == nil else { return nil } 45 | let localeSelf = self.replacingOccurrences(of: decimalPoint, with: ".") 46 | return Double(localeSelf) 47 | } 48 | 49 | /** 50 | * Splits a string into an array of string components. 51 | * 52 | * - parameter by: The character to split on. 53 | * - parameter maxSplits: The maximum number of splits to perform. If 0, all possible splits are made. 54 | * 55 | * - returns: An array of string components. 56 | */ 57 | func split(by: Character, maxSplits: Int = 0) -> [String] { 58 | var s = [String]() 59 | var numSplits = 0 60 | 61 | var curIdx = self.startIndex 62 | for i in self.characters.indices { 63 | let c = self[i] 64 | if c == by && (maxSplits == 0 || numSplits < maxSplits) { 65 | #if swift(>=3.2) 66 | s.append(String(self[curIdx..=3.2) 77 | s.append(String(self[curIdx.. String { 95 | var s = self 96 | var currentLength = self.characters.count 97 | 98 | while currentLength < width { 99 | s.append(padChar) 100 | currentLength += 1 101 | } 102 | 103 | return s 104 | } 105 | 106 | /** 107 | * Wraps a string to the specified width. 108 | * 109 | * This just does simple greedy word-packing, it doesn't go full Knuth-Plass. 110 | * If a single word is longer than the line width, it will be placed (unsplit) 111 | * on a line by itself. 112 | * 113 | * - parameter atWidth: The maximum length of a line. 114 | * - parameter wrapBy: The line break character to use. 115 | * - parameter splitBy: The character to use when splitting the string into words. 116 | * 117 | * - returns: A new string, wrapped at the given width. 118 | */ 119 | func wrapped(atWidth width: Int, wrapBy: Character = "\n", splitBy: Character = " ") -> String { 120 | var s = "" 121 | var currentLineWidth = 0 122 | 123 | for word in self.split(by: splitBy) { 124 | let wordLength = word.characters.count 125 | 126 | if currentLineWidth + wordLength + 1 > width { 127 | /* Word length is greater than line length, can't wrap */ 128 | if wordLength >= width { 129 | s += word 130 | } 131 | 132 | s.append(wrapBy) 133 | currentLineWidth = 0 134 | } 135 | 136 | currentLineWidth += wordLength + 1 137 | s += word 138 | s.append(splitBy) 139 | } 140 | 141 | return s 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/Package.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Package.swift 3 | * Copyright (c) 2015 Ben Gollmer. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import PackageDescription 19 | 20 | let package = Package( 21 | name: "CommandLine", 22 | exclude: ["script"] 23 | ) 24 | -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/Tests/CommandLineKitTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | NSHumanReadableCopyright 24 | Copyright © 2014 Ben Gollmer. Licensed under the Apache License, Version 2.0. 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * LinuxMain.swift 3 | * Copyright (c) 2015 Ben Gollmer. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import XCTest 19 | @testable import CommandLineKitTests 20 | 21 | XCTMain([testCase(CommandLineTests.allTests), testCase(StringExtensionTests.allTests)]) 22 | -------------------------------------------------------------------------------- /Carthage/Checkouts/CommandLine/script/test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | cd "$(dirname $0)/../" 5 | 6 | BUILD_PATH=".build" 7 | if [ "$(uname)" != "Darwin" ]; then 8 | BUILD_PATH=".build-linux" 9 | fi 10 | 11 | locale-gen sv_SE.UTF-8 12 | 13 | swift build -Xlinker -L/usr/local/lib --build-path $BUILD_PATH -v 14 | swift test -Xlinker -L/usr/local/lib --build-path $BUILD_PATH 15 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | 20 | #CocoaPods 21 | Pods 22 | 23 | #Carthage 24 | Carthage/Build 25 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | script: "xcodebuild test -workspace SwiftyJSON.xcworkspace -scheme \"SwiftyJSON iOS\" -destination \"platform=iOS Simulator,name=iPhone 5\"" 3 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Example/Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // SwiftyJSON.h 2 | // 3 | // Copyright (c) 2014 Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | import SwiftyJSON 25 | 26 | @UIApplicationMain 27 | class AppDelegate: UIResponder, UIApplicationDelegate { 28 | 29 | var window: UIWindow? 30 | 31 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 32 | 33 | let navigationController = self.window?.rootViewController as! UINavigationController 34 | let viewController = navigationController.topViewController as! ViewController 35 | 36 | if let file = NSBundle(forClass:AppDelegate.self).pathForResource("SwiftyJSONTests", ofType: "json") { 37 | let data = NSData(contentsOfFile: file)! 38 | let json = JSON(data:data) 39 | viewController.json = json 40 | } else { 41 | viewController.json = JSON.null 42 | } 43 | 44 | return true 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Example/Example/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "extent" : "full-screen", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "filename" : "Default@2x.png", 15 | "minimum-system-version" : "7.0", 16 | "orientation" : "portrait", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "orientation" : "portrait", 21 | "idiom" : "ipad", 22 | "extent" : "full-screen", 23 | "minimum-system-version" : "7.0", 24 | "scale" : "1x" 25 | }, 26 | { 27 | "orientation" : "landscape", 28 | "idiom" : "ipad", 29 | "extent" : "full-screen", 30 | "minimum-system-version" : "7.0", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "orientation" : "portrait", 35 | "idiom" : "ipad", 36 | "extent" : "full-screen", 37 | "minimum-system-version" : "7.0", 38 | "scale" : "2x" 39 | }, 40 | { 41 | "orientation" : "landscape", 42 | "idiom" : "ipad", 43 | "extent" : "full-screen", 44 | "minimum-system-version" : "7.0", 45 | "scale" : "2x" 46 | } 47 | ], 48 | "info" : { 49 | "version" : 1, 50 | "author" : "xcode" 51 | } 52 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Example/Example/Images.xcassets/LaunchImage.launchimage/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Carthage/Checkouts/SwiftyJSON/Example/Example/Images.xcassets/LaunchImage.launchimage/Default@2x.png -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Example/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Example/Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // SwiftyJSON.h 2 | // 3 | // Copyright (c) 2014 Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | import SwiftyJSON 25 | 26 | class ViewController: UITableViewController { 27 | 28 | var json: JSON = JSON.null 29 | 30 | // MARK: - Table view data source 31 | 32 | override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 33 | return 1 34 | } 35 | 36 | override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 37 | switch self.json.type { 38 | case Type.Array, Type.Dictionary: 39 | return self.json.count 40 | default: 41 | return 1 42 | } 43 | } 44 | 45 | override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 46 | let cell = tableView.dequeueReusableCellWithIdentifier("JSONCell", forIndexPath: indexPath) as UITableViewCell 47 | 48 | let row = indexPath.row 49 | 50 | switch self.json.type { 51 | case .Array: 52 | cell.textLabel?.text = "\(row)" 53 | cell.detailTextLabel?.text = self.json.arrayValue.description 54 | case .Dictionary: 55 | let key: AnyObject = self.json.dictionaryValue.keys.array[row] 56 | let value = self.json[key as! String] 57 | cell.textLabel?.text = "\(key)" 58 | cell.detailTextLabel?.text = value.description 59 | default: 60 | cell.textLabel?.text = "" 61 | cell.detailTextLabel?.text = self.json.description 62 | } 63 | 64 | return cell 65 | } 66 | 67 | // MARK: - Navigation 68 | 69 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { 70 | 71 | var nextController: UIViewController? 72 | switch UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch) { 73 | case .OrderedSame, .OrderedDescending: 74 | nextController = (segue.destinationViewController as! UINavigationController).topViewController 75 | case .OrderedAscending: 76 | nextController = segue.destinationViewController 77 | } 78 | 79 | if let indexPath = self.tableView.indexPathForSelectedRow { 80 | let row = indexPath.row 81 | var nextJson: JSON = JSON.null 82 | switch self.json.type { 83 | case .Array: 84 | nextJson = self.json[row] 85 | case .Dictionary where row < self.json.dictionaryValue.count: 86 | let key = self.json.dictionaryValue.keys.array[row] 87 | if let value = self.json.dictionary?[key] { 88 | nextJson = value 89 | } 90 | default: 91 | print("") 92 | } 93 | (nextController as! ViewController).json = nextJson 94 | print(nextJson) 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Ruoyu Fu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Source/Info-OSX.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Source/Info-iOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Source/Info-tvOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Source/Info-watchOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Source/SwiftyJSON.h: -------------------------------------------------------------------------------- 1 | // SwiftyJSON.h 2 | // 3 | // Copyright (c) 2014 Ruoyu Fu, Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Foundation; 24 | 25 | //! Project version number for SwiftyJSON. 26 | FOUNDATION_EXPORT double SwiftyJSONVersionNumber; 27 | 28 | //! Project version string for SwiftyJSON. 29 | FOUNDATION_EXPORT const unsigned char SwiftyJSONVersionString[]; 30 | 31 | 32 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/SwiftyJSON.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "SwiftyJSON" 3 | s.version = "2.3.1" 4 | s.summary = "SwiftyJSON makes it easy to deal with JSON data in Swift" 5 | s.homepage = "https://github.com/SwiftyJSON/SwiftyJSON" 6 | s.license = { :type => "MIT" } 7 | s.authors = { "lingoer" => "lingoerer@gmail.com", "tangplin" => "tangplin@gmail.com" } 8 | 9 | s.requires_arc = true 10 | s.osx.deployment_target = "10.9" 11 | s.ios.deployment_target = "8.0" 12 | s.watchos.deployment_target = "2.0" 13 | s.tvos.deployment_target = "9.0" 14 | s.source = { :git => "https://github.com/SwiftyJSON/SwiftyJSON.git", :tag => "2.3.1"} 15 | s.source_files = "Source/*.swift" 16 | end 17 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/SwiftyJSON.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/SwiftyJSON.xcodeproj/xcshareddata/xcschemes/SwiftyJSON OSX.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 79 | 85 | 86 | 87 | 88 | 89 | 90 | 96 | 97 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/SwiftyJSON.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/SwiftyJSON.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/ArrayTests.swift: -------------------------------------------------------------------------------- 1 | // ArrayTests.swift 2 | // 3 | // Copyright (c) 2014 Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import XCTest 24 | import SwiftyJSON 25 | 26 | class ArrayTests: XCTestCase { 27 | 28 | func testSingleDimensionalArraysGetter() { 29 | let array = ["1","2", "a", "B", "D"] 30 | let json = JSON(array) 31 | XCTAssertEqual((json.array![0] as JSON).string!, "1") 32 | XCTAssertEqual((json.array![1] as JSON).string!, "2") 33 | XCTAssertEqual((json.array![2] as JSON).string!, "a") 34 | XCTAssertEqual((json.array![3] as JSON).string!, "B") 35 | XCTAssertEqual((json.array![4] as JSON).string!, "D") 36 | } 37 | 38 | func testSingleDimensionalArraysSetter() { 39 | let array = ["1","2", "a", "B", "D"] 40 | var json = JSON(array) 41 | json.arrayObject = ["111", "222"] 42 | XCTAssertEqual((json.array![0] as JSON).string!, "111") 43 | XCTAssertEqual((json.array![1] as JSON).string!, "222") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/DictionaryTests.swift: -------------------------------------------------------------------------------- 1 | // DictionaryTests.swift 2 | // 3 | // Copyright (c) 2014 Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import XCTest 24 | import SwiftyJSON 25 | 26 | class DictionaryTests: XCTestCase { 27 | 28 | func testGetter() { 29 | let dictionary = ["number":9823.212, "name":"NAME", "list":[1234, 4.212], "object":["sub_number":877.2323, "sub_name":"sub_name"], "bool":true] 30 | let json = JSON(dictionary) 31 | //dictionary 32 | XCTAssertEqual((json.dictionary!["number"]! as JSON).double!, 9823.212) 33 | XCTAssertEqual((json.dictionary!["name"]! as JSON).string!, "NAME") 34 | XCTAssertEqual(((json.dictionary!["list"]! as JSON).array![0] as JSON).int!, 1234) 35 | XCTAssertEqual(((json.dictionary!["list"]! as JSON).array![1] as JSON).double!, 4.212) 36 | XCTAssertEqual((((json.dictionary!["object"]! as JSON).dictionaryValue)["sub_number"]! as JSON).double!, 877.2323) 37 | XCTAssertTrue(json.dictionary!["null"] == nil) 38 | //dictionaryValue 39 | XCTAssertEqual(((((json.dictionaryValue)["object"]! as JSON).dictionaryValue)["sub_name"]! as JSON).string!, "sub_name") 40 | XCTAssertEqual((json.dictionaryValue["bool"]! as JSON).bool!, true) 41 | XCTAssertTrue(json.dictionaryValue["null"] == nil) 42 | XCTAssertTrue(JSON.null.dictionaryValue == [:]) 43 | //dictionaryObject 44 | XCTAssertEqual(json.dictionaryObject!["number"]! as? Double, 9823.212) 45 | XCTAssertTrue(json.dictionaryObject!["null"] == nil) 46 | XCTAssertTrue(JSON.null.dictionaryObject == nil) 47 | } 48 | 49 | func testSetter() { 50 | var json:JSON = ["test":"case"] 51 | XCTAssertEqual(json.dictionaryObject! as! [String : String], ["test":"case"]) 52 | json.dictionaryObject = ["name":"NAME"] 53 | XCTAssertEqual(json.dictionaryObject! as! [String : String], ["name":"NAME"]) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/Info-OSX.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/Info-iOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/Info-tvOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/LiteralConvertibleTests.swift: -------------------------------------------------------------------------------- 1 | // LiteralConvertibleTests.swift 2 | // 3 | // Copyright (c) 2014 Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import XCTest 24 | import SwiftyJSON 25 | 26 | class LiteralConvertibleTests: XCTestCase { 27 | 28 | func testNumber() { 29 | var json:JSON = 1234567890.876623 30 | XCTAssertEqual(json.int!, 1234567890) 31 | XCTAssertEqual(json.intValue, 1234567890) 32 | XCTAssertEqual(json.double!, 1234567890.876623) 33 | XCTAssertEqual(json.doubleValue, 1234567890.876623) 34 | XCTAssertTrue(json.float! == 1234567890.876623) 35 | XCTAssertTrue(json.floatValue == 1234567890.876623) 36 | } 37 | 38 | func testBool() { 39 | var jsonTrue:JSON = true 40 | XCTAssertEqual(jsonTrue.bool!, true) 41 | XCTAssertEqual(jsonTrue.boolValue, true) 42 | var jsonFalse:JSON = false 43 | XCTAssertEqual(jsonFalse.bool!, false) 44 | XCTAssertEqual(jsonFalse.boolValue, false) 45 | } 46 | 47 | func testString() { 48 | var json:JSON = "abcd efg, HIJK;LMn" 49 | XCTAssertEqual(json.string!, "abcd efg, HIJK;LMn") 50 | XCTAssertEqual(json.stringValue, "abcd efg, HIJK;LMn") 51 | } 52 | 53 | func testNil() { 54 | let jsonNil_1:JSON = nil 55 | XCTAssert(jsonNil_1 == nil) 56 | let jsonNil_2:JSON = JSON(NSNull) 57 | XCTAssert(jsonNil_2 != nil) 58 | let jsonNil_3:JSON = JSON([1:2]) 59 | XCTAssert(jsonNil_3 != nil) 60 | } 61 | 62 | func testArray() { 63 | let json:JSON = [1,2,"4",5,"6"] 64 | XCTAssertEqual(json.array!, [1,2,"4",5,"6"]) 65 | XCTAssertEqual(json.arrayValue, [1,2,"4",5,"6"]) 66 | } 67 | 68 | func testDictionary() { 69 | let json:JSON = ["1":2,"2":2,"three":3,"list":["aa","bb","dd"]] 70 | XCTAssertEqual(json.dictionary!, ["1":2,"2":2,"three":3,"list":["aa","bb","dd"]]) 71 | XCTAssertEqual(json.dictionaryValue, ["1":2,"2":2,"three":3,"list":["aa","bb","dd"]]) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/PerformanceTests.swift: -------------------------------------------------------------------------------- 1 | // PerformanceTests.swift 2 | // 3 | // Copyright (c) 2014 Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import XCTest 24 | import SwiftyJSON 25 | 26 | class PerformanceTests: XCTestCase { 27 | 28 | var testData: NSData! 29 | 30 | override func setUp() { 31 | super.setUp() 32 | 33 | if let file = NSBundle(forClass:PerformanceTests.self).pathForResource("Tests", ofType: "json") { 34 | self.testData = NSData(contentsOfFile: file) 35 | } else { 36 | XCTFail("Can't find the test JSON file") 37 | } 38 | } 39 | 40 | override func tearDown() { 41 | // Put teardown code here. This method is called after the invocation of each test method in the class. 42 | super.tearDown() 43 | } 44 | 45 | func testInitPerformance() { 46 | self.measureBlock() { 47 | for _ in 1...100 { 48 | let json = JSON(data:self.testData) 49 | XCTAssertTrue(json != JSON.null) 50 | } 51 | } 52 | } 53 | 54 | func testObjectMethodPerformance() { 55 | var json = JSON(data:self.testData) 56 | self.measureBlock() { 57 | for _ in 1...100 { 58 | let object:AnyObject? = json.object 59 | XCTAssertTrue(object != nil) 60 | } 61 | } 62 | } 63 | 64 | func testArrayMethodPerformance() { 65 | let json = JSON(data:self.testData) 66 | self.measureBlock() { 67 | for _ in 1...100 { 68 | autoreleasepool{ 69 | let array = json.array 70 | XCTAssertTrue(array?.count > 0) 71 | } 72 | } 73 | } 74 | } 75 | 76 | func testDictionaryMethodPerformance() { 77 | let json = JSON(data:testData)[0] 78 | self.measureBlock() { 79 | for _ in 1...100 { 80 | autoreleasepool{ 81 | let dictionary = json.dictionary 82 | XCTAssertTrue(dictionary?.count > 0) 83 | } 84 | } 85 | } 86 | } 87 | 88 | func testRawStringMethodPerformance() { 89 | let json = JSON(data:testData) 90 | self.measureBlock() { 91 | for _ in 1...100 { 92 | autoreleasepool{ 93 | let string = json.rawString() 94 | XCTAssertTrue(string != nil) 95 | } 96 | } 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/PrintableTests.swift: -------------------------------------------------------------------------------- 1 | // PrintableTests.swift 2 | // 3 | // Copyright (c) 2014 Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import XCTest 24 | import SwiftyJSON 25 | 26 | class PrintableTests: XCTestCase { 27 | func testNumber() { 28 | let json:JSON = 1234567890.876623 29 | XCTAssertEqual(json.description, "1234567890.876623") 30 | XCTAssertEqual(json.debugDescription, "1234567890.876623") 31 | } 32 | 33 | func testBool() { 34 | let jsonTrue:JSON = true 35 | XCTAssertEqual(jsonTrue.description, "true") 36 | XCTAssertEqual(jsonTrue.debugDescription, "true") 37 | let jsonFalse:JSON = false 38 | XCTAssertEqual(jsonFalse.description, "false") 39 | XCTAssertEqual(jsonFalse.debugDescription, "false") 40 | } 41 | 42 | func testString() { 43 | let json:JSON = "abcd efg, HIJK;LMn" 44 | XCTAssertEqual(json.description, "abcd efg, HIJK;LMn") 45 | XCTAssertEqual(json.debugDescription, "abcd efg, HIJK;LMn") 46 | } 47 | 48 | func testNil() { 49 | let jsonNil_1:JSON = nil 50 | XCTAssertEqual(jsonNil_1.description, "null") 51 | XCTAssertEqual(jsonNil_1.debugDescription, "null") 52 | let jsonNil_2:JSON = JSON(NSNull()) 53 | XCTAssertEqual(jsonNil_2.description, "null") 54 | XCTAssertEqual(jsonNil_2.debugDescription, "null") 55 | } 56 | 57 | func testArray() { 58 | let json:JSON = [1,2,"4",5,"6"] 59 | var description = json.description.stringByReplacingOccurrencesOfString("\n", withString: "") 60 | description = description.stringByReplacingOccurrencesOfString(" ", withString: "") 61 | XCTAssertEqual(description, "[1,2,\"4\",5,\"6\"]") 62 | XCTAssertTrue(json.description.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) > 0) 63 | XCTAssertTrue(json.debugDescription.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) > 0) 64 | } 65 | 66 | func testDictionary() { 67 | let json:JSON = ["1":2,"2":"two", "3":3] 68 | var debugDescription = json.debugDescription.stringByReplacingOccurrencesOfString("\n", withString: "") 69 | debugDescription = debugDescription.stringByReplacingOccurrencesOfString(" ", withString: "") 70 | XCTAssertTrue(json.description.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) > 0) 71 | XCTAssertTrue(debugDescription.rangeOfString("\"1\":2", options: NSStringCompareOptions.CaseInsensitiveSearch) != nil) 72 | XCTAssertTrue(debugDescription.rangeOfString("\"2\":\"two\"", options: NSStringCompareOptions.CaseInsensitiveSearch) != nil) 73 | XCTAssertTrue(debugDescription.rangeOfString("\"3\":3", options: NSStringCompareOptions.CaseInsensitiveSearch) != nil) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/RawRepresentableTests.swift: -------------------------------------------------------------------------------- 1 | // RawRepresentableTests.swift 2 | // 3 | // Copyright (c) 2014 Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import XCTest 24 | import SwiftyJSON 25 | 26 | class RawRepresentableTests: XCTestCase { 27 | 28 | func testNumber() { 29 | var json:JSON = JSON(rawValue: 948394394.347384 as NSNumber)! 30 | XCTAssertEqual(json.int!, 948394394) 31 | XCTAssertEqual(json.intValue, 948394394) 32 | XCTAssertEqual(json.double!, 948394394.347384) 33 | XCTAssertEqual(json.doubleValue, 948394394.347384) 34 | XCTAssertTrue(json.float! == 948394394.347384) 35 | XCTAssertTrue(json.floatValue == 948394394.347384) 36 | 37 | let object: AnyObject = json.rawValue 38 | XCTAssertEqual(object as? Int, 948394394) 39 | XCTAssertEqual(object as? Double, 948394394.347384) 40 | XCTAssertTrue(object as! Float == 948394394.347384) 41 | XCTAssertEqual(object as? NSNumber, 948394394.347384) 42 | } 43 | 44 | func testBool() { 45 | var jsonTrue:JSON = JSON(rawValue: true as NSNumber)! 46 | XCTAssertEqual(jsonTrue.bool!, true) 47 | XCTAssertEqual(jsonTrue.boolValue, true) 48 | 49 | var jsonFalse:JSON = JSON(rawValue: false)! 50 | XCTAssertEqual(jsonFalse.bool!, false) 51 | XCTAssertEqual(jsonFalse.boolValue, false) 52 | 53 | let objectTrue: AnyObject = jsonTrue.rawValue 54 | XCTAssertEqual(objectTrue as? Int, 1) 55 | XCTAssertEqual(objectTrue as? Double, 1.0) 56 | XCTAssertEqual(objectTrue as? Bool, true) 57 | XCTAssertEqual(objectTrue as? NSNumber, NSNumber(bool: true)) 58 | 59 | let objectFalse: AnyObject = jsonFalse.rawValue 60 | XCTAssertEqual(objectFalse as? Int, 0) 61 | XCTAssertEqual(objectFalse as? Double, 0.0) 62 | XCTAssertEqual(objectFalse as? Bool, false) 63 | XCTAssertEqual(objectFalse as? NSNumber, NSNumber(bool: false)) 64 | } 65 | 66 | func testString() { 67 | let string = "The better way to deal with JSON data in Swift." 68 | if let json:JSON = JSON(rawValue: string) { 69 | XCTAssertEqual(json.string!, string) 70 | XCTAssertEqual(json.stringValue, string) 71 | XCTAssertTrue(json.array == nil) 72 | XCTAssertTrue(json.dictionary == nil) 73 | XCTAssertTrue(json.null == nil) 74 | XCTAssertTrue(json.error == nil) 75 | XCTAssertTrue(json.type == .String) 76 | XCTAssertEqual(json.object as? String, string) 77 | } else { 78 | XCTFail("Should not run into here") 79 | } 80 | 81 | let object: AnyObject = JSON(rawValue: string)!.rawValue 82 | XCTAssertEqual(object as? String, string) 83 | } 84 | 85 | func testNil() { 86 | if let _ = JSON(rawValue: NSObject()) { 87 | XCTFail("Should not run into here") 88 | } 89 | } 90 | 91 | func testArray() { 92 | let array = [1,2,"3",4102,"5632", "abocde", "!@# $%^&*()"] as NSArray 93 | if let json:JSON = JSON(rawValue: array) { 94 | XCTAssertEqual(json, JSON(array)) 95 | } 96 | 97 | let object: AnyObject = JSON(rawValue: array)!.rawValue 98 | XCTAssertTrue(array == object as! NSArray) 99 | } 100 | 101 | func testDictionary() { 102 | let dictionary = ["1":2,"2":2,"three":3,"list":["aa","bb","dd"]] as NSDictionary 103 | if let json:JSON = JSON(rawValue: dictionary) { 104 | XCTAssertEqual(json, JSON(dictionary)) 105 | } 106 | 107 | let object: AnyObject = JSON(rawValue: dictionary)!.rawValue 108 | XCTAssertTrue(dictionary == object as! NSDictionary) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/RawTests.swift: -------------------------------------------------------------------------------- 1 | // RawTests.swift 2 | // 3 | // Copyright (c) 2014 Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import XCTest 24 | import SwiftyJSON 25 | 26 | class RawTests: XCTestCase { 27 | 28 | func testRawData() { 29 | let json: JSON = ["somekey" : "some string value"] 30 | let expectedRawData = "{\"somekey\":\"some string value\"}".dataUsingEncoding(NSUTF8StringEncoding) 31 | do { 32 | let data: NSData = try json.rawData() 33 | XCTAssertEqual(expectedRawData, data) 34 | } catch _ { 35 | XCTFail() 36 | } 37 | } 38 | 39 | func testInvalidJSONForRawData() { 40 | let json: JSON = "...xyz" 41 | do { 42 | try json.rawData() 43 | } catch let error as NSError { 44 | XCTAssertEqual(error.code, ErrorInvalidJSON) 45 | } 46 | } 47 | 48 | func testArray() { 49 | let json:JSON = [1, "2", 3.12, NSNull(), true, ["name": "Jack"]] 50 | let data: NSData? 51 | do { 52 | data = try json.rawData() 53 | } catch _ { 54 | data = nil 55 | } 56 | let string = json.rawString() 57 | XCTAssertTrue (data != nil) 58 | XCTAssertTrue (string!.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) > 0) 59 | print(string!) 60 | } 61 | 62 | func testDictionary() { 63 | let json:JSON = ["number":111111.23456789, "name":"Jack", "list":[1,2,3,4], "bool":false, "null":NSNull()] 64 | let data: NSData? 65 | do { 66 | data = try json.rawData() 67 | } catch _ { 68 | data = nil 69 | } 70 | let string = json.rawString() 71 | XCTAssertTrue (data != nil) 72 | XCTAssertTrue (string!.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) > 0) 73 | print(string!) 74 | } 75 | 76 | func testString() { 77 | let json:JSON = "I'm a json" 78 | print(json.rawString()) 79 | XCTAssertTrue(json.rawString() == "I'm a json") 80 | } 81 | 82 | func testNumber() { 83 | let json:JSON = 123456789.123 84 | print(json.rawString()) 85 | XCTAssertTrue(json.rawString() == "123456789.123") 86 | } 87 | 88 | func testBool() { 89 | let json:JSON = true 90 | print(json.rawString()) 91 | XCTAssertTrue(json.rawString() == "true") 92 | } 93 | 94 | func testNull() { 95 | let json:JSON = nil 96 | print(json.rawString()) 97 | XCTAssertTrue(json.rawString() == "null") 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Carthage/Checkouts/SwiftyJSON/Tests/StringTests.swift: -------------------------------------------------------------------------------- 1 | // StringTests.swift 2 | // 3 | // Copyright (c) 2014 Pinglin Tang 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import XCTest 24 | import SwiftyJSON 25 | 26 | class StringTests: XCTestCase { 27 | 28 | func testString() { 29 | //getter 30 | var json = JSON("abcdefg hijklmn;opqrst.?+_()") 31 | XCTAssertEqual(json.string!, "abcdefg hijklmn;opqrst.?+_()") 32 | XCTAssertEqual(json.stringValue, "abcdefg hijklmn;opqrst.?+_()") 33 | 34 | json.string = "12345?67890.@#" 35 | XCTAssertEqual(json.string!, "12345?67890.@#") 36 | XCTAssertEqual(json.stringValue, "12345?67890.@#") 37 | } 38 | 39 | func testURL() { 40 | let json = JSON("http://github.com") 41 | XCTAssertEqual(json.URL!, NSURL(string:"http://github.com")!) 42 | } 43 | 44 | func testURLPercentEscapes() { 45 | let emDash = "\\u2014" 46 | let urlString = "http://examble.com/unencoded" + emDash + "string" 47 | let encodedURLString = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) 48 | let json = JSON(urlString) 49 | XCTAssertEqual(json.URL!, NSURL(string: encodedURLString!)!, "Wrong unpacked ") 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Excerptor.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Excerptor.xcodeproj/xcshareddata/xcschemes/Excerptor.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Excerptor.xcodeproj/xcshareddata/xcschemes/Install SIMBL Plugin PDFReaderPlugin.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 11 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 66 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 88 | 89 | 95 | 96 | 97 | 98 | 100 | 101 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /Excerptor.xcodeproj/xcshareddata/xcschemes/PDFReaderPlugin.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /Excerptor/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // excerptor 4 | // 5 | // Created by Chen Guo on 17/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import PreferencePanes 11 | 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | lazy var preferencesWindowController: PreferencesWindowController = PreferencesWindowController(windowNibName: NSNib.Name(rawValue: "PreferencesWindow")) 15 | 16 | func applicationWillFinishLaunching(_ notification: Notification) { 17 | 18 | preferencesWindowController.showPreferencesOnlyOnceIfNecessaryAfterDelay(0.3) 19 | 20 | let servicesProvider = ServicesProvider() 21 | NSApplication.shared.servicesProvider = servicesProvider 22 | 23 | let appleEventManager: NSAppleEventManager = NSAppleEventManager.shared() 24 | appleEventManager.setEventHandler(self, andSelector: #selector(handleGetURLEvent(_:withReplyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL)) 25 | } 26 | 27 | func applicationDidBecomeActive(_ notification: Notification) { 28 | preferencesWindowController.showPreferencesOnlyOnceIfNecessaryAfterDelay(0.3) 29 | } 30 | 31 | @objc func handleGetURLEvent(_ event: NSAppleEventDescriptor, withReplyEvent: NSAppleEventDescriptor) { 32 | PreferencesWindowController.needShowPreferences = false 33 | if let theURLString = event.forKeyword(AEKeyword(keyDirectObject))?.stringValue { 34 | if let link = AnnotationLink(linkString: theURLString) ?? SelectionLink(linkString: theURLString) { 35 | PasteboardHelper.writeExcerptorPasteboardWithLocation(link.location) 36 | let applicationName: String 37 | switch Preferences.sharedPreferences.appForOpenPDF { 38 | case .preview: 39 | applicationName = "Preview.app" 40 | case .skim: 41 | applicationName = "Skim.app" 42 | } 43 | NSWorkspace().openFile(link.getFilePath(), withApplication: applicationName, andDeactivate: true) 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Excerptor/FileTemplate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FileTemplate.swift 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 6/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct FileTemplate { 12 | 13 | // attribute templates 14 | let folderPath: String 15 | let fileName: String 16 | let fileExtension: String 17 | let tags: [String] 18 | let content: String 19 | let creationDate: String 20 | let modificationDate: String 21 | 22 | // swiftlint:disable function_body_length 23 | func writeToFileWithPropertyGettersDictionary(_ propertyGettersByPlaceholder: [String: () -> String]) { 24 | let folderPath = self.folderPath.stringByReplacingWithDictionary(propertyGettersByPlaceholder) 25 | var fileName = self.fileName.stringByReplacingWithDictionary(propertyGettersByPlaceholder) 26 | let content = self.content.stringByReplacingWithDictionary(propertyGettersByPlaceholder) 27 | let fileExtension = self.fileExtension.stringByReplacingWithDictionary(propertyGettersByPlaceholder) 28 | let tags = self.tags.map { return $0.stringByReplacingWithDictionary(propertyGettersByPlaceholder) } 29 | let creationDateString = self.creationDate.stringByReplacingWithDictionary(propertyGettersByPlaceholder) 30 | let creationDate = Date.dateFromISO8601String(creationDateString) 31 | let modificationDateString = self.modificationDate.stringByReplacingWithDictionary(propertyGettersByPlaceholder) 32 | let modificationDate = Date.dateFromISO8601String(modificationDateString) 33 | 34 | if fileName.isEmpty { 35 | fileName = "Note " + String(String(content.hash).suffix(4)) // Hope lucky. 36 | } else { 37 | fileName = fileName.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) 38 | .replacingOccurrences(of: "/", with: "%2F", options: [], range: nil) 39 | .replacingOccurrences(of: ":", with: "%3A", options: [], range: nil) 40 | .replacingOccurrences(of: "\n", with: " ", options: [], range: nil) 41 | if fileName.count > 192 { 42 | fileName = String(fileName.prefix(192)) + "…" 43 | } 44 | } 45 | 46 | do { 47 | try FileManager.default.createDirectory(atPath: folderPath, withIntermediateDirectories: true, attributes: nil) 48 | } catch let error as NSError { 49 | exitWithError(error.localizedDescription) 50 | } 51 | 52 | let filePathWithoutExtension = URL(fileURLWithPath: folderPath).appendingPathComponent(fileName).path 53 | let expandedFilePathWithoutExtension = NSString(string: filePathWithoutExtension).expandingTildeInPath 54 | var filePath = fileExtension.isEmpty ? filePathWithoutExtension : URL(fileURLWithPath: expandedFilePathWithoutExtension).appendingPathExtension(fileExtension).path 55 | var serialNumber = 2 // if the filename exists, append serial number 2, 3, 4, ... 56 | while FileManager.default.fileExists(atPath: filePath) { 57 | filePath = fileExtension.isEmpty ? filePathWithoutExtension + " \(serialNumber)" : URL(fileURLWithPath: expandedFilePathWithoutExtension + " \(serialNumber)").appendingPathExtension(fileExtension).path 58 | serialNumber += 1 59 | if serialNumber > 10_000 { 60 | exitWithError("Too many duplicated file names: \(filePath)") 61 | } 62 | } 63 | 64 | do { 65 | try content.write(toFile: filePath, atomically: true, encoding: String.Encoding.utf8) 66 | } catch let error as NSError { 67 | exitWithError("Could not write to file: \(filePath)\n" + error.localizedDescription) 68 | } 69 | 70 | do { 71 | try (URL(fileURLWithPath: filePath) as NSURL).setResourceValue(tags, forKey: URLResourceKey.tagNamesKey) 72 | } catch let error as NSError { 73 | exitWithError("Could not set resource value \(tags.description) for key NSURLTagNamesKey to file: \(filePath)\n" + error.localizedDescription) 74 | } 75 | 76 | do { 77 | try FileManager.default.setAttributes([FileAttributeKey.creationDate: creationDate as Any], ofItemAtPath: filePath) 78 | } catch let error as NSError { 79 | exitWithError("Could not set creation data: \(String(describing: creationDate?.description)) of \(filePath)\n" + error.localizedDescription) 80 | } 81 | 82 | do { 83 | try FileManager.default.setAttributes([FileAttributeKey.modificationDate: modificationDate as Any], ofItemAtPath: filePath) 84 | } catch let error as NSError { 85 | exitWithError("Could not set modification date: \(String(describing: modificationDate?.description)) of \(filePath)\n" + error.localizedDescription) 86 | } 87 | } 88 | // swiftlint:enable function_body_length 89 | 90 | } 91 | -------------------------------------------------------------------------------- /Excerptor/Helpers/PasteboardHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasteboardHelper.swift 3 | // excerptor 4 | // 5 | // Created by Chen Guo on 17/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class PasteboardHelper { 12 | 13 | struct Constants { 14 | static let OutputPasteboardName = "name.guoc.excerptor.ExcerptorToPDFReader" 15 | static let InputPasteboardName = "name.guoc.excerptor.PDFReaderToExcerptor" 16 | static let PasteboardType = "org.nspasteboard.TransientType" 17 | static let ExcerptorToPDFReaderHeader = "ExcerptorToPDFReader:" 18 | static let PDFReaderToExcerptorHeader = "PDFReaderToExcerptor:" 19 | } 20 | 21 | class func writeGeneralPasteboardWith(_ selectionLink: SelectionLink?) -> Bool { 22 | if let selectionLink = selectionLink { 23 | let pasteboard = NSPasteboard.general 24 | pasteboard.clearContents() 25 | let attributedString = NSAttributedString(string: selectionLink.selectionTextArrayInOneLine, attributes: [NSAttributedStringKey.link: selectionLink.string]) 26 | return pasteboard.writeObjects([attributedString]) 27 | && pasteboard.setString(selectionLink.string, forType: NSPasteboard.PasteboardType.string) 28 | } 29 | return false 30 | } 31 | 32 | class func readExcerptorPasteboard() -> Location? { 33 | let pasteboard = NSPasteboard(name: NSPasteboard.Name(rawValue: Constants.InputPasteboardName)) 34 | guard let data = pasteboard.data(forType: NSPasteboard.PasteboardType(rawValue: Constants.PasteboardType)) else { 35 | return nil 36 | } 37 | guard let unarchivedObject = NSKeyedUnarchiver.unarchiveObject(with: data) else { 38 | exitWithError("Could not unarchive object with data " + data.description) 39 | } 40 | guard let location = unarchivedObject as? Location else { 41 | if let errorMessage = unarchivedObject as? NSString { 42 | notifyWithError("Error message in pasteboard", informativeText: String(errorMessage)) 43 | return nil 44 | } else { 45 | exitWithError("Could not convert unarchived object to location " + (unarchivedObject as AnyObject).description) 46 | } 47 | } 48 | return location 49 | } 50 | 51 | class func writeExcerptorPasteboardWithLocation(_ location: Location) { 52 | let pasteboard = NSPasteboard(name: NSPasteboard.Name(rawValue: Constants.OutputPasteboardName)) 53 | pasteboard.clearContents() 54 | let data = NSKeyedArchiver.archivedData(withRootObject: location) 55 | guard pasteboard.setData(data, forType: NSPasteboard.PasteboardType(rawValue: Constants.PasteboardType)) else { 56 | exitWithError("Could not write into pasteboard with excerpt location") 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Excerptor/Helpers/delay-helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // delay-helper.swift 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 19/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | // http://stackoverflow.com/a/24318861/3157231 10 | 11 | func delay(_ delay: Double, closure: @escaping () -> Void) { 12 | DispatchQueue.main.asyncAfter( 13 | deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure) 14 | } 15 | -------------------------------------------------------------------------------- /Excerptor/Helpers/error-helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // error-helper.swift 3 | // excerptor 4 | // 5 | // Created by Chen Guo on 17/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | func printToStandardError(_ string: String) { 10 | let stderr = FileHandle.standardError 11 | let stringWithAppInfo = "Excerptor: \(string)" 12 | stderr.write(stringWithAppInfo.data(using: String.Encoding.utf8, allowLossyConversion: false)!) 13 | } 14 | 15 | func printlnToStandardError(_ string: String) { 16 | printToStandardError("\(string)\n") 17 | } 18 | 19 | var runningInCLI = false 20 | 21 | func exitWithError(_ err: String) -> Never { 22 | if runningInCLI { 23 | printlnToStandardError(err) 24 | exit(1) 25 | } else { 26 | notifyWithError("Excerptor error", informativeText: err) 27 | fatalError(err) 28 | } 29 | } 30 | 31 | private let userNotificationCenterDelegate = UserNotificationCenterDelegate() 32 | 33 | private struct Constants { 34 | static let PDFFilePathToRevealInFinder = "PDFFilePathToRevealInFinder" 35 | } 36 | 37 | func notifyWithUserNotification(_ userNotification: NSUserNotification) { 38 | if runningInCLI { 39 | var err = "" 40 | if let title = userNotification.title { 41 | err += "\(title)\n" 42 | } 43 | if let subtitle = userNotification.subtitle { 44 | err += "\(subtitle)\n" 45 | } 46 | if let informativeText = userNotification.informativeText { 47 | err += "\(informativeText)\n" 48 | } 49 | if let userInfo = userNotification.userInfo { 50 | err += userInfo.values.map { $0 as? String ?? "" }.joined(separator: "\n") 51 | err += "\n" 52 | } 53 | printlnToStandardError(err) 54 | } else { 55 | let userNotificationCenter = NSUserNotificationCenter.default 56 | userNotificationCenter.delegate = userNotificationCenterDelegate 57 | userNotificationCenter.deliver(userNotification) 58 | } 59 | } 60 | 61 | func notifyWithError(_ err: String, informativeText: String?) { 62 | let userNotification = NSUserNotification() 63 | let errComponents = err.components(separatedBy: "\n") 64 | switch errComponents.count { 65 | case 1: 66 | userNotification.title = errComponents[0] 67 | case 2: 68 | userNotification.title = errComponents[0] 69 | userNotification.subtitle = errComponents[1] 70 | default: 71 | userNotification.title = err 72 | } 73 | userNotification.informativeText = informativeText 74 | userNotification._ignoresDoNotDisturb = true 75 | notifyWithUserNotification(userNotification) 76 | } 77 | 78 | func notifyPDFFileNotFoundInDNtpWith(_ filePath: String, replacingPlaceholder: String) { 79 | let userNotification = NSUserNotification() 80 | userNotification.title = "Could Not Find The PDF File In DEVONthink" 81 | userNotification.subtitle = "\(replacingPlaceholder) applied instead" 82 | userNotification.informativeText = URL(fileURLWithPath: filePath).lastPathComponent 83 | let path = URL(fileURLWithPath: filePath).standardizedFileURL.path 84 | userNotification.userInfo = [Constants.PDFFilePathToRevealInFinder: path] 85 | userNotification._ignoresDoNotDisturb = true 86 | notifyWithUserNotification(userNotification) 87 | } 88 | 89 | class UserNotificationCenterDelegate: NSObject, NSUserNotificationCenterDelegate { 90 | 91 | // Notifications may be suppressed if the application is already frontmost, 92 | // this extension is to make sure notifications can be showed in this case, 93 | // although the case doesn't happen. 94 | func userNotificationCenter(_ center: NSUserNotificationCenter, shouldPresent notification: NSUserNotification) -> Bool { 95 | return true 96 | } 97 | 98 | // Prevent from showing preferences window when users click on notification. 99 | func userNotificationCenter(_ center: NSUserNotificationCenter, didActivate notification: NSUserNotification) { 100 | PreferencesWindowController.needShowPreferences = false 101 | if let userInfo = notification.userInfo, let filePath = userInfo[Constants.PDFFilePathToRevealInFinder] as? String { 102 | let url = URL(fileURLWithPath: filePath, isDirectory: false) 103 | NSWorkspace.shared.activateFileViewerSelecting([url]) 104 | } 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /Excerptor/Helpers/nscolor-helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // nscolor-helper.swift 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 22/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | extension NSColor { 10 | 11 | var colorComponents: [CGFloat] { 12 | let numberOfComponents = self.numberOfComponents 13 | let components = UnsafeMutablePointer.allocate(capacity: numberOfComponents) 14 | self.getComponents(components) 15 | return Array(UnsafeMutableBufferPointer(start: components, count: numberOfComponents)) 16 | } 17 | 18 | var hexDescription: String! { 19 | if let color = self.usingColorSpace(NSColorSpace.genericRGB) { 20 | let r = color.redComponent 21 | let g = color.greenComponent 22 | let b = color.blueComponent 23 | return String(format: "%02X%02X%02X", Int(r * 255.0), Int(g * 255.0), Int(b * 255.0)) 24 | } else { 25 | return "Unrecognized color" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Excerptor/Helpers/nsdate-helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // nsdate-helper.swift 3 | // excerptor 4 | // 5 | // Created by Chen Guo on 17/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | extension Date { 10 | static func dateFromISO8601String(_ ISO8601String: String) -> Date! { 11 | let ISO8601DateFormatter = DateFormatter() 12 | ISO8601DateFormatter.locale = Locale(identifier: "en_US_POSIX") 13 | ISO8601DateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" 14 | if let date = ISO8601DateFormatter.date(from: ISO8601String) { 15 | return date 16 | } else { 17 | exitWithError("Could not parse date format") 18 | } 19 | } 20 | // swiftlint:enable variable_name 21 | 22 | func ISO8601String() -> String { 23 | let ISO8601DateFormatter = DateFormatter() 24 | ISO8601DateFormatter.locale = Locale(identifier: "en_US_POSIX") 25 | ISO8601DateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" 26 | return ISO8601DateFormatter.string(from: self) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Excerptor/Helpers/string-helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // string-helper.swift 3 | // excerptor 4 | // 5 | // Created by Chen Guo on 17/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | let URIUnreservedCharacterSet = CharacterSet(charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~") 10 | // swiftlint:enable variable_name 11 | 12 | extension String { 13 | func stringByRemovingPrefix(_ prefix: String) -> String { 14 | if let r = prefix.range(of: prefix, options: .anchored, range: nil, locale: nil) { 15 | return String(self[r.upperBound...]) 16 | } 17 | return self 18 | } 19 | 20 | func stringByReplacingWithDictionary(_ stringGettersByPlaceholder: [String: () -> String]) -> String { 21 | 22 | var string = self 23 | for (placeholder, stringGetter) in stringGettersByPlaceholder { 24 | if string.range(of: placeholder, options: [], range: nil, locale: nil) == nil { 25 | continue 26 | } else { 27 | string = string.replacingOccurrences(of: placeholder, with: stringGetter(), options: [], range: nil) 28 | } 29 | } 30 | return string 31 | } 32 | 33 | var isDNtpUUID: Bool { 34 | let regex = try! NSRegularExpression(pattern: "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", options: [.caseInsensitive]) // swiftlint:disable:this force_try 35 | let range = NSRange(location: 0, length: count) 36 | guard let firstMatch = regex.firstMatch(in: self, options: [.anchored], range: range)?.range else { 37 | return false 38 | } 39 | return NSEqualRanges(firstMatch, range) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Excerptor/Link.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Link.swift 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 9/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class Link { 12 | static let head = "excerptor://" 13 | let fileID: FileID! 14 | 15 | init!() { 16 | fileID = nil 17 | return nil 18 | } 19 | 20 | init(fileID: FileID) { 21 | self.fileID = fileID 22 | } 23 | 24 | convenience init(filePath: String) { 25 | self.init(fileID: FileID.filePath(filePath)) 26 | } 27 | 28 | convenience init(dntpUuid: String) { 29 | self.init(fileID: FileID.dNtpUuid(dntpUuid)) 30 | } 31 | 32 | convenience init(filePathOrDNtpUuid: String) { 33 | self.init(fileID: FileID(filePathOrDNtpUuid: filePathOrDNtpUuid)) 34 | } 35 | 36 | required init?(location: Location, text: String?) { 37 | self.fileID = nil 38 | return nil 39 | } 40 | 41 | required init?(linkString: String) { 42 | if linkString.hasPrefix(Link.head) { 43 | let linkStringWithoutHead = linkString.stringByRemovingPrefix(Link.head) 44 | fileID = FileID(filePathOrDNtpUuid: linkStringWithoutHead) 45 | return 46 | } else { 47 | exitWithError("Incorrect link format") 48 | } 49 | } 50 | 51 | var string: String { 52 | return "\(Link.head)\(fileID.presentativeString)" 53 | } 54 | 55 | var isFilePathLinkType: Bool { 56 | return fileID.isFilePath 57 | } 58 | 59 | var isDNtpUuidLinkType: Bool { 60 | return !(fileID.isFilePath) 61 | } 62 | 63 | var filePathOrDNtpUuid: String { 64 | return isFilePathLinkType ? "file://\(getFilePath())" : "x-devonthink-item://\(getDNtpUuid())" 65 | } 66 | 67 | func getFilePath() -> String { 68 | return fileID.getFilePath() 69 | } 70 | 71 | func getDNtpUuid() -> String? { 72 | return fileID.getDNtpUuid() 73 | } 74 | 75 | var location: Location { 76 | fatalError("Property location in subclass of Link must be overridden") 77 | } 78 | 79 | func getDNtpUuidTypeLink() -> Link? { 80 | fatalError("getDNtpUuidTypeLink in subclass of Link must be overridden") 81 | } 82 | 83 | func getFilePathTypeLink() -> Link? { 84 | fatalError("getFilePathTypeLink in subclass of Link must be overridden") 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Excerptor/PreferencesDefaultValues(DNtp).plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SelectionLinkPlainText 6 | {{SelectionLink_DEVONthinkUUID}} 7 | SelectionLinkRichText 8 | [{{SelectionText}}]({{SelectionLink_DEVONthinkUUID}}) 9 | SelectionFileContent 10 | > {{SelectionText}} 11 | 12 | [{{PDFFileName}}]({{SelectionLink_DEVONthinkUUID}}) 13 | 14 | {{CreationDate}} excerpted by {{UserName}} 15 | 16 | AnnotationFileContent 17 | > {{AnnotationText}} 18 | 19 | {{NoteText}} 20 | 21 | [{{PDFFileName}}]({{AnnotationLink_DEVONthinkUUID}}) 22 | 23 | {{AnnotationDate}} annotated by {{Author}} 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Excerptor/PreferencesDefaultValues.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AppForOpenPDF 6 | 0 7 | SelectionLinkPlainText 8 | {{SelectionLink_FilePath}} 9 | SelectionLinkRichTextSameAsPlainText 10 | 11 | SelectionLinkRichText 12 | [{{SelectionText}}]({{SelectionLink_FilePath}}) 13 | ShowNotificationWhenFileNotFoundInDNtpForSelectionLink 14 | 15 | SelectionFilesLocation 16 | ~/Documents/Selections/{{PDFFileName_NoExtension}}/ 17 | SelectionFileName 18 | {{SelectionText}} 19 | SelectionFileExtension 20 | md 21 | SelectionFileTags 22 | Excerpt 23 | SelectionFileContent 24 | > {{SelectionText}} 25 | 26 | [{{PDFFileName}}]({{SelectionLink_FilePath}}) 27 | 28 | {{CreationDate}} excerpted by {{UserName}} 29 | 30 | ShowNotificationWhenFileNotFoundInDNtpForSelectionFile 31 | 32 | AnnotationFilesLocation 33 | ~/Documents/Annotations/{{PDFFileName_NoExtension}}/ 34 | AnnotationFileName 35 | {{AnnotationText}} 36 | AnnotationFileExtension 37 | md 38 | AnnotationFileTags 39 | {{Type}} 40 | AnnotationFileContent 41 | > {{AnnotationText}} 42 | 43 | {{NoteText}} 44 | 45 | [{{PDFFileName}}]({{AnnotationLink_FilePath}}) 46 | 47 | {{AnnotationDate}} annotated by {{Author}} 48 | 49 | ShowNotificationWhenFileNotFoundInDNtpForAnnotationFile 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Excerptor/PreferencesWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Excerptor/PreferencesWindowController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Preferences.swift 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 19/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import PreferencePanes 11 | 12 | class PreferencesWindowController: NSWindowController { 13 | 14 | static var needShowPreferences = true 15 | 16 | fileprivate var prefPane: NSPreferencePane! = { 17 | if let pathToPrefPaneBundle = Bundle.main.path(forResource: "PrefsPane", ofType: "prefPane", inDirectory: "PreferencePanes"), 18 | let prefBundle = Bundle(path: pathToPrefPaneBundle), 19 | let prefPaneClass = prefBundle.principalClass as? NSPreferencePane.Type { 20 | // swiftlint:enable opening_brace 21 | var prefPane = prefPaneClass.init(bundle: prefBundle) 22 | (prefPane as PrefsPane).setDelegate!(Preferences.sharedPreferences) 23 | return prefPane 24 | } else { 25 | exitWithError("Could not load preference pane bundle") 26 | } 27 | }() 28 | 29 | override func windowDidLoad() { 30 | super.windowDidLoad() 31 | 32 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. 33 | } 34 | 35 | func showPreferencesIfNecessary() { 36 | if !PreferencesWindowController.needShowPreferences { 37 | return 38 | } 39 | 40 | if window!.contentView!.subviews.count == 0 { 41 | prefPane.loadMainView() 42 | prefPane.willSelect() 43 | let prefView = prefPane.mainView 44 | window!.setContentSize(prefView.frame.size) 45 | window!.contentView!.addSubview(prefView) 46 | prefPane.didSelect() 47 | } 48 | 49 | NSApp.activate(ignoringOtherApps: true) 50 | showWindow(self) 51 | } 52 | 53 | func showPreferencesOnlyOnceIfNecessaryAfterDelay(_ delaySeconds: TimeInterval) { 54 | delay(0.3) { 55 | self.showPreferencesIfNecessary() 56 | PreferencesWindowController.needShowPreferences = true 57 | } 58 | } 59 | 60 | } 61 | 62 | @objc public protocol PrefsPane { 63 | @objc optional func setDelegate(_ delegate: PrefsPaneDelegate) 64 | } 65 | 66 | extension NSPreferencePane: PrefsPane {} 67 | -------------------------------------------------------------------------------- /Excerptor/Supporting Files/Excerptor-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "Location.h" 6 | #import "SelectionLocation.h" 7 | #import "SelectionLineLocation.h" 8 | #import "AnnotationLocation.h" 9 | #import "NSUserNotification-Private.h" 10 | #import "PrefsPaneDelegate.h" 11 | #import "PrefsPane.h" 12 | #import "SkimNotes/SkimNotes.h" 13 | -------------------------------------------------------------------------------- /Excerptor/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.2 21 | CFBundleSignature 22 | ???? 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleURLName 27 | name.guoc.excerptor.Excerptor 28 | CFBundleURLSchemes 29 | 30 | excerptor 31 | 32 | 33 | 34 | CFBundleVersion 35 | 4 36 | LSMinimumSystemVersion 37 | $(MACOSX_DEPLOYMENT_TARGET) 38 | LSUIElement 39 | 40 | NSHumanReadableCopyright 41 | Copyright © 2015 guoc. All rights reserved. 42 | NSMainNibFile 43 | MainMenu 44 | NSPrincipalClass 45 | NSApplication 46 | NSServices 47 | 48 | 49 | NSKeyEquivalent 50 | 51 | default 52 | E 53 | 54 | NSMenuItem 55 | 56 | default 57 | Excerptor: Excerpt Selection To Pasteboard 58 | 59 | NSMessage 60 | getSelectionLink 61 | NSPortName 62 | Excerptor 63 | NSRequiredContext 64 | 65 | 66 | NSApplicationIdentifier 67 | com.apple.Preview 68 | 69 | 70 | NSApplicationIdentifier 71 | net.sourceforge.skim-app.skim 72 | 73 | 74 | NSReturnTypes 75 | 76 | NSStringPboardType 77 | 78 | NSSendTypes 79 | 80 | public.text 81 | 82 | NSServiceDescription 83 | Get a link to Excerptor app which can redirect to Preview/Skim app with current selection selected. 84 | 85 | 86 | NSMenuItem 87 | 88 | default 89 | Excerptor: Excerpt Selection To File 90 | 91 | NSMessage 92 | getSelectionFile 93 | NSPortName 94 | Excerptor 95 | NSRequiredContext 96 | 97 | 98 | NSApplicationIdentifier 99 | com.apple.Preview 100 | 101 | 102 | NSApplicationIdentifier 103 | net.sourceforge.skim-app.skim 104 | 105 | 106 | NSReturnTypes 107 | 108 | NSStringPboardType 109 | 110 | NSSendTypes 111 | 112 | public.text 113 | 114 | NSServiceDescription 115 | Create a selection file containing current text selection in a specified location (configure in Excerptor). 116 | 117 | 118 | NSMenuItem 119 | 120 | default 121 | Excerptor: Get Annotation Files 122 | 123 | NSMessage 124 | getAnnotationFiles 125 | NSPortName 126 | Excerptor 127 | NSReturnTypes 128 | 129 | NSSendFileTypes 130 | 131 | com.adobe.pdf 132 | 133 | NSSendTypes 134 | 135 | NSFilenamesPboardType 136 | 137 | NSServiceDescription 138 | Create annotation files containing current PDF file's annotations in a specified location (configure in Excerptor). 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /Excerptor/Supporting Files/NSUserNotification-Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSUserNotification-Private.h 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 20/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | @interface NSUserNotification (Private) 10 | 11 | @property BOOL _ignoresDoNotDisturb; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Excerptor/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 20/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import CommandLineKit 12 | 13 | if CommandLine.argc == 1 || CommandLine.argc == 3 && CommandLine.arguments[1] == "-NSDocumentRevisionsDebugMode" && CommandLine.arguments[2] == "YES" { 14 | _ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) 15 | exit(0) 16 | } 17 | 18 | enum Operation: String { 19 | case list 20 | case export 21 | } 22 | 23 | enum ExtractionType: String { 24 | case annotation 25 | } 26 | 27 | enum Format: String { 28 | case text 29 | case JSON 30 | } 31 | 32 | let operation = EnumOption(longFlag: "operation", helpMessage: "'list' / 'export', 'list' by default.") 33 | let extractionType = EnumOption(longFlag: "type", helpMessage: "Type of data to be extracted, currently only supports 'annotation', by default 'annotation'.") 34 | let format = EnumOption(longFlag: "format", helpMessage: "Display format, currently only supports 'text' and 'JSON', 'text' by default.") 35 | let sourceFilePath = StringOption(longFlag: "source-file", required: true, helpMessage: "Path of the PDF file which containing required data.") 36 | 37 | let cli = CommandLine() 38 | 39 | cli.addOptions(operation, extractionType, format, sourceFilePath) 40 | 41 | runningInCLI = true 42 | do { 43 | try cli.parse() 44 | } catch { 45 | cli.printUsage(error) 46 | exit(EX_USAGE) 47 | } 48 | 49 | let unwrappedOperation = operation.value ?? Operation.list 50 | 51 | let unwrappedExtractionType = extractionType.value ?? ExtractionType.annotation 52 | 53 | let unwrappedFormat = format.value ?? Format.text 54 | let outputFormat: OutputFormat = { 55 | switch unwrappedFormat { 56 | case .JSON: 57 | return .json 58 | case .text: 59 | return .text 60 | } 61 | }() 62 | 63 | guard let unwrappedSourceFilePath = sourceFilePath.value else { 64 | exitWithError("--source-file is required") 65 | } 66 | guard let sourceFileURL = NSURL(fileURLWithPath: unwrappedSourceFilePath, isDirectory: false).standardizingPath else { 67 | exitWithError("\(unwrappedSourceFilePath): Incorrect source file path") 68 | } 69 | 70 | switch unwrappedOperation { 71 | 72 | case Operation.list: 73 | printAnnotationsFrom(sourceFileURL, withFormat: outputFormat) 74 | 75 | case Operation.export: 76 | writePDFAnnotationsFrom(sourceFileURL) 77 | } 78 | 79 | runningInCLI = false 80 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Headers/PDFDocument_SKNExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDFDocument_SKNExtensions.h 3 | // SkimNotes 4 | // 5 | // Created by Christiaan Hofman on 6/15/08. 6 | /* 7 | This software is Copyright (c) 2008-2014 8 | Christiaan Hofman. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | - Neither the name of Christiaan Hofman nor the names of any 23 | contributors may be used to endorse or promote products derived 24 | from this software without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /*! 40 | @header 41 | @abstract An PDFDocument category to add Skim note annotations to a PDFDocument. 42 | @discussion This header file provides API for an PDFDocument category to add Skim note annotations to a PDFDocument. 43 | */ 44 | #import 45 | #import 46 | 47 | 48 | /*! 49 | @category 50 | @abstract Provides methods to add Skim notes to a PDFDocument. 51 | @discussion This category can be used to add Skim notes from their properties to a PDFDocument or easily load a PDFDocument including attached Skim notes. 52 | */ 53 | @interface PDFDocument (SKNExtensions) 54 | 55 | /*! 56 | @method 57 | @abstract Initializes a new PDFDocument from a file or PDF bundle, adding Skim notes from the extended attributes of the file or the contents of the PDF bundle. The added Skim notes are returned by reference as an array of PDFAnnotations. 58 | @discussion Initializes a new PDFDocument using initWithURL:, reads Skim notes from theextended attributes or the bundle, and adds new PDFAnnotation objects to the document initialized by the found Skim note properties. 59 | @param url The URL of the PDF file or PDF bundle. 60 | @param notes An array of PDFAnnotation objects initialized using the Skim note properties read from the extended attributes or bundled Skim file. 61 | @result The initialized PDFDocument. 62 | */ 63 | - (id)initWithURL:(NSURL *)url readSkimNotes:(NSArray **)notes; 64 | 65 | /*! 66 | @method 67 | @abstract Adds new Skim notes from an array of property dictionaries to the receiver, and returns the added Skim notes as an array of PDFAnnotations. 68 | @discussion This method initializes new PDFAnnotation objects from the passed in properties and adds them to the appropriate pages of the PDFDocument. 69 | @param noteDicts An array of dictionaries containing Skim note properties as returned by the properties of PDFAnnotation objects. 70 | @result An array of PDFAnnotation objects initialized using the Skim note properties read from the extended attributes or bundled Skim file. 71 | */ 72 | - (NSArray *)addSkimNotesWithProperties:(NSArray *)noteDicts; 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Headers/SKNPDFAnnotationNote.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKNPDFAnnotationNote.h 3 | // SkimNotes 4 | // 5 | // Created by Christiaan Hofman on 6/15/08. 6 | /* 7 | This software is Copyright (c) 2008-2014 8 | Christiaan Hofman. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | - Neither the name of Christiaan Hofman nor the names of any 23 | contributors may be used to endorse or promote products derived 24 | from this software without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /*! 40 | @header 41 | @abstract A concrete PDFAnnotation subclass representing a Skim anchored note. 42 | @discussion This header file declares API for a concrete PDFAnnotation class representing a Skim anchored note. 43 | */ 44 | #import 45 | #import 46 | 47 | /*! 48 | @discussion Global string for annotation text key. 49 | */ 50 | extern NSString *SKNPDFAnnotationTextKey; 51 | /*! 52 | @discussion Global string for annotation image key. 53 | */ 54 | extern NSString *SKNPDFAnnotationImageKey; 55 | 56 | /*! 57 | @discussion Default size of an anchored note. 58 | */ 59 | extern NSSize SKNPDFAnnotationNoteSize; 60 | 61 | /*! 62 | @abstract A concrete PDFAnnotation subclass, a subclass of PDFAnnotationText, representing a Skim anchored note. 63 | @discussion This is a PDFAnnotationText subclass containing a separate short string value, a longer rich text property, and an image property. 64 | */ 65 | @interface SKNPDFAnnotationNote : PDFAnnotationText 66 | { 67 | NSString *string; 68 | NSImage *image; 69 | NSTextStorage *textStorage; 70 | NSAttributedString *text; 71 | NSArray *texts; 72 | } 73 | 74 | /*! 75 | @abstract This is overridden and different from the contents. 76 | @discussion This should give a short string value for the anchored note annotation. 77 | @result A string representing the string value associated with the annotation. 78 | */ 79 | - (NSString *)string; 80 | 81 | /*! 82 | @abstract This is overridden and different from the contents. 83 | @discussion This should set the short string value of the annotation. This updates the contents using updateContents. 84 | @param newString The new string value for the annotation. 85 | */ 86 | - (void)setString:(NSString *)newString; 87 | 88 | /*! 89 | @abstract The rich text of the annotation. 90 | @discussion This is the longer rich text contents of the anchored note annotation. 91 | */ 92 | - (NSAttributedString *)text; 93 | 94 | /*! 95 | @abstract Sets the rich text of the annotation. 96 | @discussion This should set the longer rich text contents of the annotation. This updates the contents using updateContents. 97 | @param newText The new rich text value for the annotation. 98 | */ 99 | - (void)setText:(NSAttributedString *)newText; 100 | 101 | /*! 102 | @abstract The image of the annotation. 103 | @discussion 104 | */ 105 | - (NSImage *)image; 106 | 107 | /*! 108 | @abstract Sets the image of the annotation. 109 | @discussion 110 | @param newImage The new image for the annotation. 111 | */ 112 | - (void)setImage:(NSImage *)newImage; 113 | 114 | /*! 115 | @abstract Synchronizes the contents of the annotation with the string and text. 116 | @discussion This sets the contents to the string value and the text appended, separated by a double space. 117 | */ 118 | - (void)updateContents; 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Headers/SkimNotes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SkimNotes.h 3 | * SkimNotes 4 | * 5 | * Created by Christiaan Hofman on 6/15/08. 6 | * 7 | This software is Copyright (c) 2008-2014 8 | Christiaan Hofman. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | - Neither the name of Christiaan Hofman nor the names of any 23 | contributors may be used to endorse or promote products derived 24 | from this software without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | #import 40 | 41 | #import 42 | 43 | #import 44 | 45 | #import 46 | #import 47 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/Dutch.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/Dutch.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/English.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/English.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/French.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/French.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/German.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/German.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 10K549 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | SkimNotes 11 | CFBundleIdentifier 12 | net.sourceforge.skim-app.framework.SkimNotes 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | SkimNotes 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.3.3 23 | DTCompiler 24 | 25 | DTPlatformBuild 26 | 10M2518 27 | DTPlatformVersion 28 | PG 29 | DTSDKBuild 30 | 10M2518 31 | DTSDKName 32 | macosx10.6 33 | DTXcode 34 | 0400 35 | DTXcodeBuild 36 | 10M2518 37 | NSHumanReadableCopyright 38 | © Christiaan M. Hofman, 2008-2014 39 | 40 | 41 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/Italian.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/Italian.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/Japanese.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/Japanese.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/Spanish.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/Spanish.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/pl.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/pl.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/ru.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/ru.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/zh_CN.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/zh_CN.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Resources/zh_TW.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Resources/zh_TW.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/SkimNotes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/SkimNotes -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Headers/PDFDocument_SKNExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDFDocument_SKNExtensions.h 3 | // SkimNotes 4 | // 5 | // Created by Christiaan Hofman on 6/15/08. 6 | /* 7 | This software is Copyright (c) 2008-2014 8 | Christiaan Hofman. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | - Neither the name of Christiaan Hofman nor the names of any 23 | contributors may be used to endorse or promote products derived 24 | from this software without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /*! 40 | @header 41 | @abstract An PDFDocument category to add Skim note annotations to a PDFDocument. 42 | @discussion This header file provides API for an PDFDocument category to add Skim note annotations to a PDFDocument. 43 | */ 44 | #import 45 | #import 46 | 47 | 48 | /*! 49 | @category 50 | @abstract Provides methods to add Skim notes to a PDFDocument. 51 | @discussion This category can be used to add Skim notes from their properties to a PDFDocument or easily load a PDFDocument including attached Skim notes. 52 | */ 53 | @interface PDFDocument (SKNExtensions) 54 | 55 | /*! 56 | @method 57 | @abstract Initializes a new PDFDocument from a file or PDF bundle, adding Skim notes from the extended attributes of the file or the contents of the PDF bundle. The added Skim notes are returned by reference as an array of PDFAnnotations. 58 | @discussion Initializes a new PDFDocument using initWithURL:, reads Skim notes from theextended attributes or the bundle, and adds new PDFAnnotation objects to the document initialized by the found Skim note properties. 59 | @param url The URL of the PDF file or PDF bundle. 60 | @param notes An array of PDFAnnotation objects initialized using the Skim note properties read from the extended attributes or bundled Skim file. 61 | @result The initialized PDFDocument. 62 | */ 63 | - (id)initWithURL:(NSURL *)url readSkimNotes:(NSArray **)notes; 64 | 65 | /*! 66 | @method 67 | @abstract Adds new Skim notes from an array of property dictionaries to the receiver, and returns the added Skim notes as an array of PDFAnnotations. 68 | @discussion This method initializes new PDFAnnotation objects from the passed in properties and adds them to the appropriate pages of the PDFDocument. 69 | @param noteDicts An array of dictionaries containing Skim note properties as returned by the properties of PDFAnnotation objects. 70 | @result An array of PDFAnnotation objects initialized using the Skim note properties read from the extended attributes or bundled Skim file. 71 | */ 72 | - (NSArray *)addSkimNotesWithProperties:(NSArray *)noteDicts; 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Headers/SKNPDFAnnotationNote.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKNPDFAnnotationNote.h 3 | // SkimNotes 4 | // 5 | // Created by Christiaan Hofman on 6/15/08. 6 | /* 7 | This software is Copyright (c) 2008-2014 8 | Christiaan Hofman. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | - Neither the name of Christiaan Hofman nor the names of any 23 | contributors may be used to endorse or promote products derived 24 | from this software without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /*! 40 | @header 41 | @abstract A concrete PDFAnnotation subclass representing a Skim anchored note. 42 | @discussion This header file declares API for a concrete PDFAnnotation class representing a Skim anchored note. 43 | */ 44 | #import 45 | #import 46 | 47 | /*! 48 | @discussion Global string for annotation text key. 49 | */ 50 | extern NSString *SKNPDFAnnotationTextKey; 51 | /*! 52 | @discussion Global string for annotation image key. 53 | */ 54 | extern NSString *SKNPDFAnnotationImageKey; 55 | 56 | /*! 57 | @discussion Default size of an anchored note. 58 | */ 59 | extern NSSize SKNPDFAnnotationNoteSize; 60 | 61 | /*! 62 | @abstract A concrete PDFAnnotation subclass, a subclass of PDFAnnotationText, representing a Skim anchored note. 63 | @discussion This is a PDFAnnotationText subclass containing a separate short string value, a longer rich text property, and an image property. 64 | */ 65 | @interface SKNPDFAnnotationNote : PDFAnnotationText 66 | { 67 | NSString *string; 68 | NSImage *image; 69 | NSTextStorage *textStorage; 70 | NSAttributedString *text; 71 | NSArray *texts; 72 | } 73 | 74 | /*! 75 | @abstract This is overridden and different from the contents. 76 | @discussion This should give a short string value for the anchored note annotation. 77 | @result A string representing the string value associated with the annotation. 78 | */ 79 | - (NSString *)string; 80 | 81 | /*! 82 | @abstract This is overridden and different from the contents. 83 | @discussion This should set the short string value of the annotation. This updates the contents using updateContents. 84 | @param newString The new string value for the annotation. 85 | */ 86 | - (void)setString:(NSString *)newString; 87 | 88 | /*! 89 | @abstract The rich text of the annotation. 90 | @discussion This is the longer rich text contents of the anchored note annotation. 91 | */ 92 | - (NSAttributedString *)text; 93 | 94 | /*! 95 | @abstract Sets the rich text of the annotation. 96 | @discussion This should set the longer rich text contents of the annotation. This updates the contents using updateContents. 97 | @param newText The new rich text value for the annotation. 98 | */ 99 | - (void)setText:(NSAttributedString *)newText; 100 | 101 | /*! 102 | @abstract The image of the annotation. 103 | @discussion 104 | */ 105 | - (NSImage *)image; 106 | 107 | /*! 108 | @abstract Sets the image of the annotation. 109 | @discussion 110 | @param newImage The new image for the annotation. 111 | */ 112 | - (void)setImage:(NSImage *)newImage; 113 | 114 | /*! 115 | @abstract Synchronizes the contents of the annotation with the string and text. 116 | @discussion This sets the contents to the string value and the text appended, separated by a double space. 117 | */ 118 | - (void)updateContents; 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Headers/SkimNotes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SkimNotes.h 3 | * SkimNotes 4 | * 5 | * Created by Christiaan Hofman on 6/15/08. 6 | * 7 | This software is Copyright (c) 2008-2014 8 | Christiaan Hofman. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | - Neither the name of Christiaan Hofman nor the names of any 23 | contributors may be used to endorse or promote products derived 24 | from this software without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | #import 40 | 41 | #import 42 | 43 | #import 44 | 45 | #import 46 | #import 47 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/Dutch.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/Dutch.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/English.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/English.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/French.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/French.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/German.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/German.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 10K549 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | SkimNotes 11 | CFBundleIdentifier 12 | net.sourceforge.skim-app.framework.SkimNotes 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | SkimNotes 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.3.3 23 | DTCompiler 24 | 25 | DTPlatformBuild 26 | 10M2518 27 | DTPlatformVersion 28 | PG 29 | DTSDKBuild 30 | 10M2518 31 | DTSDKName 32 | macosx10.6 33 | DTXcode 34 | 0400 35 | DTXcodeBuild 36 | 10M2518 37 | NSHumanReadableCopyright 38 | © Christiaan M. Hofman, 2008-2014 39 | 40 | 41 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/Italian.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/Italian.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/Japanese.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/Japanese.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/Spanish.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/Spanish.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/pl.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/pl.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/ru.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/ru.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/zh_CN.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/zh_CN.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/Resources/zh_TW.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/Resources/zh_TW.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/A/SkimNotes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/A/SkimNotes -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Headers/PDFDocument_SKNExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDFDocument_SKNExtensions.h 3 | // SkimNotes 4 | // 5 | // Created by Christiaan Hofman on 6/15/08. 6 | /* 7 | This software is Copyright (c) 2008-2014 8 | Christiaan Hofman. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | - Neither the name of Christiaan Hofman nor the names of any 23 | contributors may be used to endorse or promote products derived 24 | from this software without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /*! 40 | @header 41 | @abstract An PDFDocument category to add Skim note annotations to a PDFDocument. 42 | @discussion This header file provides API for an PDFDocument category to add Skim note annotations to a PDFDocument. 43 | */ 44 | #import 45 | #import 46 | 47 | 48 | /*! 49 | @category 50 | @abstract Provides methods to add Skim notes to a PDFDocument. 51 | @discussion This category can be used to add Skim notes from their properties to a PDFDocument or easily load a PDFDocument including attached Skim notes. 52 | */ 53 | @interface PDFDocument (SKNExtensions) 54 | 55 | /*! 56 | @method 57 | @abstract Initializes a new PDFDocument from a file or PDF bundle, adding Skim notes from the extended attributes of the file or the contents of the PDF bundle. The added Skim notes are returned by reference as an array of PDFAnnotations. 58 | @discussion Initializes a new PDFDocument using initWithURL:, reads Skim notes from theextended attributes or the bundle, and adds new PDFAnnotation objects to the document initialized by the found Skim note properties. 59 | @param url The URL of the PDF file or PDF bundle. 60 | @param notes An array of PDFAnnotation objects initialized using the Skim note properties read from the extended attributes or bundled Skim file. 61 | @result The initialized PDFDocument. 62 | */ 63 | - (id)initWithURL:(NSURL *)url readSkimNotes:(NSArray **)notes; 64 | 65 | /*! 66 | @method 67 | @abstract Adds new Skim notes from an array of property dictionaries to the receiver, and returns the added Skim notes as an array of PDFAnnotations. 68 | @discussion This method initializes new PDFAnnotation objects from the passed in properties and adds them to the appropriate pages of the PDFDocument. 69 | @param noteDicts An array of dictionaries containing Skim note properties as returned by the properties of PDFAnnotation objects. 70 | @result An array of PDFAnnotation objects initialized using the Skim note properties read from the extended attributes or bundled Skim file. 71 | */ 72 | - (NSArray *)addSkimNotesWithProperties:(NSArray *)noteDicts; 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Headers/SKNPDFAnnotationNote.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKNPDFAnnotationNote.h 3 | // SkimNotes 4 | // 5 | // Created by Christiaan Hofman on 6/15/08. 6 | /* 7 | This software is Copyright (c) 2008-2014 8 | Christiaan Hofman. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | - Neither the name of Christiaan Hofman nor the names of any 23 | contributors may be used to endorse or promote products derived 24 | from this software without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /*! 40 | @header 41 | @abstract A concrete PDFAnnotation subclass representing a Skim anchored note. 42 | @discussion This header file declares API for a concrete PDFAnnotation class representing a Skim anchored note. 43 | */ 44 | #import 45 | #import 46 | 47 | /*! 48 | @discussion Global string for annotation text key. 49 | */ 50 | extern NSString *SKNPDFAnnotationTextKey; 51 | /*! 52 | @discussion Global string for annotation image key. 53 | */ 54 | extern NSString *SKNPDFAnnotationImageKey; 55 | 56 | /*! 57 | @discussion Default size of an anchored note. 58 | */ 59 | extern NSSize SKNPDFAnnotationNoteSize; 60 | 61 | /*! 62 | @abstract A concrete PDFAnnotation subclass, a subclass of PDFAnnotationText, representing a Skim anchored note. 63 | @discussion This is a PDFAnnotationText subclass containing a separate short string value, a longer rich text property, and an image property. 64 | */ 65 | @interface SKNPDFAnnotationNote : PDFAnnotationText 66 | { 67 | NSString *string; 68 | NSImage *image; 69 | NSTextStorage *textStorage; 70 | NSAttributedString *text; 71 | NSArray *texts; 72 | } 73 | 74 | /*! 75 | @abstract This is overridden and different from the contents. 76 | @discussion This should give a short string value for the anchored note annotation. 77 | @result A string representing the string value associated with the annotation. 78 | */ 79 | - (NSString *)string; 80 | 81 | /*! 82 | @abstract This is overridden and different from the contents. 83 | @discussion This should set the short string value of the annotation. This updates the contents using updateContents. 84 | @param newString The new string value for the annotation. 85 | */ 86 | - (void)setString:(NSString *)newString; 87 | 88 | /*! 89 | @abstract The rich text of the annotation. 90 | @discussion This is the longer rich text contents of the anchored note annotation. 91 | */ 92 | - (NSAttributedString *)text; 93 | 94 | /*! 95 | @abstract Sets the rich text of the annotation. 96 | @discussion This should set the longer rich text contents of the annotation. This updates the contents using updateContents. 97 | @param newText The new rich text value for the annotation. 98 | */ 99 | - (void)setText:(NSAttributedString *)newText; 100 | 101 | /*! 102 | @abstract The image of the annotation. 103 | @discussion 104 | */ 105 | - (NSImage *)image; 106 | 107 | /*! 108 | @abstract Sets the image of the annotation. 109 | @discussion 110 | @param newImage The new image for the annotation. 111 | */ 112 | - (void)setImage:(NSImage *)newImage; 113 | 114 | /*! 115 | @abstract Synchronizes the contents of the annotation with the string and text. 116 | @discussion This sets the contents to the string value and the text appended, separated by a double space. 117 | */ 118 | - (void)updateContents; 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Headers/SkimNotes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SkimNotes.h 3 | * SkimNotes 4 | * 5 | * Created by Christiaan Hofman on 6/15/08. 6 | * 7 | This software is Copyright (c) 2008-2014 8 | Christiaan Hofman. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | - Neither the name of Christiaan Hofman nor the names of any 23 | contributors may be used to endorse or promote products derived 24 | from this software without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | #import 40 | 41 | #import 42 | 43 | #import 44 | 45 | #import 46 | #import 47 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/Dutch.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/Dutch.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/English.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/English.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/French.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/French.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/German.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/German.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 10K549 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | SkimNotes 11 | CFBundleIdentifier 12 | net.sourceforge.skim-app.framework.SkimNotes 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | SkimNotes 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.3.3 23 | DTCompiler 24 | 25 | DTPlatformBuild 26 | 10M2518 27 | DTPlatformVersion 28 | PG 29 | DTSDKBuild 30 | 10M2518 31 | DTSDKName 32 | macosx10.6 33 | DTXcode 34 | 0400 35 | DTXcodeBuild 36 | 10M2518 37 | NSHumanReadableCopyright 38 | © Christiaan M. Hofman, 2008-2014 39 | 40 | 41 | -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/Italian.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/Italian.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/Japanese.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/Japanese.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/Spanish.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/Spanish.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/pl.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/pl.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/ru.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/ru.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/zh_CN.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/zh_CN.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/Resources/zh_TW.lproj/SkimNotes.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/Resources/zh_TW.lproj/SkimNotes.strings -------------------------------------------------------------------------------- /Frameworks/SkimNotes.framework/Versions/Current/SkimNotes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/Frameworks/SkimNotes.framework/Versions/Current/SkimNotes -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 guoc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /PDFKit Extensions/CGPoint.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension CGPoint { 4 | func pointByOffsetting(dx: CGFloat, dy: CGFloat) -> CGPoint { // swiftlint:disable:this identifier_name 5 | return CGPoint(x: x + dx, y: y + dy) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /PDFKit Extensions/PDFAnnotation.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Quartz 3 | 4 | // MARK: - PDFAnnotation Extension 5 | 6 | extension PDFAnnotation { 7 | 8 | var annotationText: String { 9 | return (self as? PDFAnnotationMarkup)?.selectionText ?? "" 10 | } 11 | 12 | var noteText: String { 13 | return isSkimNote() ? string() : (contents ?? "") 14 | } 15 | 16 | var typeName: String { 17 | return type ?? "Unrecognized" 18 | } 19 | 20 | var author: String { 21 | return userName ?? "" 22 | } 23 | 24 | var pageIndex: Int { 25 | return page!.pageIndex 26 | } 27 | 28 | var date: Date { 29 | return modificationDate! 30 | } 31 | 32 | var pdfFilePath: String { 33 | return self.page!.document!.documentURL!.path 34 | } 35 | 36 | var pdfFileName: String { 37 | return URL(fileURLWithPath: pdfFilePath).lastPathComponent 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /PDFKit Extensions/PDFAnnotationMarkup.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Quartz 3 | 4 | extension PDFAnnotationMarkup { 5 | 6 | // MARK: - Public 7 | 8 | var selectionText: String { 9 | let selections: [PDFSelection] 10 | if #available(OSX 10.11, *) { 11 | selections = rectsInPageCoordinate.map { (self.page?.selection(for: $0.insetBy(dx: -1.0, dy: -1.0))!)! } 12 | } else { 13 | selections = horizontalCentralLinesInPageCoordinate.map { (self.page?.selection(from: $0.startPoint, to: $0.endPoint)!)! } 14 | } 15 | let selectionStrings = selections.map({ $0.string ?? "" }).map({$0.trimmingCharacters(in: CharacterSet.newlines)}) 16 | return selectionStrings.joined(separator: " ") 17 | } 18 | 19 | // MARK: - Private 20 | 21 | fileprivate var rects: [CGRect] { 22 | let quadrilateralPoints = self.quadrilateralPoints().map { ($0 as AnyObject).pointValue as NSPoint} 23 | assert(quadrilateralPoints.count % 4 == 0, "Incorrect number of annotation markup quadrilateral points") 24 | let groupedQuadrilateralPoints = [Int](0.. (startPoint: CGPoint, endPoint: CGPoint) in 36 | let x = rect.origin.x, y = rect.origin.y, width = rect.width, height = rect.height 37 | let startPoint = CGPoint(x: x, y: y + height / 2.0) 38 | let endPoint = CGPoint(x: x + width, y: y + height / 2.0) 39 | return (startPoint: startPoint, endPoint: endPoint) 40 | } 41 | } 42 | 43 | fileprivate var horizontalCentralLinesInPageCoordinate: [(startPoint: CGPoint, endPoint: CGPoint)] { 44 | let origin = self.bounds.origin 45 | return horizontalCentralLines.map { ($0.startPoint.pointByOffsetting(dx: origin.x, dy: origin.y), $0.endPoint.pointByOffsetting(dx: origin.x, dy: origin.y)) } 46 | } 47 | 48 | // MARK: - Helper Methods 49 | 50 | fileprivate func smallestRectangleEnclosing(_ points: [CGPoint]) -> CGRect { 51 | 52 | guard let minX = (points.map { $0.x }).min(), 53 | let maxX = (points.map { $0.x }).max(), 54 | let minY = (points.map { $0.y }).min(), 55 | let maxY = (points.map { $0.y }).max() else { 56 | exitWithError("Empty points array passed in smallestRectangleEnclosing") 57 | } 58 | 59 | return CGRect(x: minX, y: minY, width: maxX - minX, height: maxY - minY) 60 | } 61 | 62 | fileprivate func smallestRectangleEnclosing(_ points: CGPoint...) -> CGRect { 63 | return smallestRectangleEnclosing(points) 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /PDFKit Extensions/PDFDocument.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PDFDocument.swift 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 21/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | import Quartz 10 | 11 | extension PDFDocument { 12 | 13 | var pages: [PDFPage] { 14 | return (0.. 10 | 11 | static NSString *const SelectionTextDelimiter = @"-"; 12 | 13 | @interface PDFSelection (BoundsDescription) 14 | 15 | - (NSRange)range; 16 | 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /PDFReaderPlugin/Helpers/PDFSelection+BoundsDescription.m: -------------------------------------------------------------------------------- 1 | // 2 | // PDFSelection+PDFSelection_Bounds.m 3 | // PDFReaderPlugin 4 | // 5 | // Created by Chen Guo on 30/04/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import "PDFSelection+BoundsDescription.h" 10 | 11 | @implementation PDFSelection (BoundsDescription) 12 | 13 | - (NSRange)range { 14 | PDFPage *page = [[self pages] firstObject]; 15 | NSString *pageString = [page string]; 16 | NSString *mySelectionString = [self string]; 17 | NSRect mySelectionRect = [self boundsForPage:page]; 18 | NSPoint mySelectionRectCenter = NSMakePoint(mySelectionRect.origin.x + mySelectionRect.size.width / 2, mySelectionRect.origin.y + mySelectionRect.size.height / 2); 19 | 20 | NSRange range = [pageString rangeOfString:mySelectionString]; 21 | NSPoint selectionRectCenter; 22 | while (range.location != NSNotFound) { 23 | PDFSelection *selection = [page selectionForRange:range]; 24 | NSRect selectionRect = [selection boundsForPage:page]; 25 | selectionRectCenter = NSMakePoint(selectionRect.origin.x + selectionRect.size.width / 2, selectionRect.origin.y + selectionRect.size.height / 2); 26 | if (fabs(selectionRectCenter.x - mySelectionRectCenter.x) < 1.0 && fabs(selectionRectCenter.y - mySelectionRectCenter.y) < 1.0) { 27 | break; 28 | } 29 | NSUInteger searchLocation = range.location + range.length; 30 | NSUInteger searchLength = [pageString length] - searchLocation; 31 | NSRange searchRange = NSMakeRange(searchLocation, searchLength); 32 | range = [pageString rangeOfString:mySelectionString options:0 range:searchRange]; 33 | } 34 | if (range.location == NSNotFound) { 35 | return NSMakeRange(NSNotFound, 0); 36 | } else { 37 | return range; 38 | } 39 | } 40 | 41 | @end 42 | 43 | -------------------------------------------------------------------------------- /PDFReaderPlugin/Helpers/PasteboardHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // PasteboardHelper.h 3 | // excerptor 4 | // 5 | // Created by Chen Guo on 17/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import "Location.h" 10 | #import "SelectionLocation.h" 11 | 12 | @interface PasteboardHelper : NSObject 13 | 14 | + (Location *)readPasteboard; 15 | + (bool)writePasteboardWithSelectionLocation: (SelectionLocation *)selectionLocation; 16 | + (bool)writePasteboardWithErrorMessage: (NSString *)errorMessage; 17 | + (void)clearInputPasteboard; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /PDFReaderPlugin/Helpers/PasteboardHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // PasteboardHelper.m 3 | // excerptor 4 | // 5 | // Created by Chen Guo on 17/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | @import AppKit; 10 | 11 | #import "PasteboardHelper.h" 12 | #import "SelectionLocation.h" 13 | 14 | @implementation PasteboardHelper 15 | 16 | static NSString *const InputPasteboardName = @"name.guoc.excerptor.ExcerptorToPDFReader"; 17 | static NSString *const OutputPasteboardName = @"name.guoc.excerptor.PDFReaderToExcerptor"; 18 | static NSString *const PasteboardType = @"org.nspasteboard.TransientType"; 19 | 20 | + (Location *)readPasteboard { 21 | NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:InputPasteboardName]; 22 | NSData *data = [pasteboard dataForType:PasteboardType]; 23 | if (!data) { 24 | return nil; 25 | } 26 | NSObject *unarchivedObject = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 27 | if (![unarchivedObject isKindOfClass:[Location class]]) { 28 | return nil; 29 | } 30 | return (Location *)unarchivedObject; 31 | } 32 | 33 | + (bool)writePasteboardWithSelectionLocation: (SelectionLocation *)selectionLocation { 34 | NSData *data = [NSKeyedArchiver archivedDataWithRootObject:selectionLocation]; 35 | NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:OutputPasteboardName]; 36 | [pasteboard clearContents]; 37 | return [pasteboard setData:data forType:PasteboardType]; 38 | } 39 | 40 | + (bool)writePasteboardWithErrorMessage: (NSString *)errorMessage { 41 | if ([[PasteboardHelper readPasteboard] isKindOfClass:[Location class]]) { 42 | return NO; 43 | } 44 | NSData *data = [NSKeyedArchiver archivedDataWithRootObject: [@"Excerptor PDFReaderPlugin: " stringByAppendingString: errorMessage]]; 45 | NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:OutputPasteboardName]; 46 | [pasteboard clearContents]; 47 | return [pasteboard setData:data forType:PasteboardType]; 48 | } 49 | 50 | + (void)clearInputPasteboard { 51 | NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:InputPasteboardName]; 52 | [pasteboard clearContents]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /PDFReaderPlugin/PDFReaderPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDFReaderPlugin.h 3 | // excerptor 4 | // 5 | // Created by Chen Guo on 17/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PDFReaderPlugin : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PDFReaderPlugin/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.2 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 4 23 | NSHumanReadableCopyright 24 | Copyright © 2015 guoc. All rights reserved. 25 | NSPrincipalClass 26 | 27 | SIMBLTargetApplications 28 | 29 | 30 | BundleIdentifier 31 | com.apple.Preview 32 | MinBundleVersion 33 | 859.21 34 | 35 | 36 | BundleIdentifier 37 | net.sourceforge.skim-app.skim 38 | MinBundleVersion 39 | 85 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /PopClipExtension/Config.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Extension Identifier 6 | name.guoc.excerptor.PopClipExtension 7 | Extension Name 8 | Excerptor 9 | Required Apps 10 | 11 | com.apple.Preview 12 | net.sourceforge.skim-app.skim 13 | 14 | Apps 15 | 16 | 17 | Name 18 | Excerptor 19 | Check Installed 20 | 21 | Link 22 | https://github.com/guoc/excerptor 23 | Bundle Identifier 24 | name.guoc.excerptor.Excerptor 25 | 26 | 27 | Actions 28 | 29 | 30 | Title 31 | Excerpt To Pasteboard 32 | Service Name 33 | Excerptor: Excerpt Selection To Pasteboard 34 | 35 | 36 | Title 37 | Excerpt To File 38 | Service Name 39 | Excerptor: Excerpt Selection To File 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /PopClipExtension/Makefile: -------------------------------------------------------------------------------- 1 | bundle_name=excerptor.popclipext 2 | 3 | excerptor.popclipextz : Config.plist 4 | mkdir ./$(bundle_name) 5 | cp $^ ./$(bundle_name)/ 6 | zip -rm $@ ./$(bundle_name) 7 | 8 | .PHONY: clean 9 | clean: 10 | rm excerptor.popclipextz 11 | -------------------------------------------------------------------------------- /PopClipExtension/excerptor.popclipextz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/PopClipExtension/excerptor.popclipextz -------------------------------------------------------------------------------- /PrefsPane/HelpWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // HelpWindowController.h 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 21/06/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HelpWindowController : NSWindowController 12 | 13 | @property (weak) IBOutlet NSTableView *tableView; 14 | 15 | @property (nonatomic) NSArray *placeholdersToShow; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /PrefsPane/HelpWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // HelpWindowController.m 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 21/06/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import "HelpWindowController.h" 10 | 11 | @interface HelpWindowController () 12 | 13 | @end 14 | 15 | @implementation HelpWindowController 16 | 17 | @synthesize placeholdersToShow = _placeholdersToShow; 18 | 19 | - (void)setPlaceholdersToShow:(NSArray *)placeholdersToShow { 20 | _placeholdersToShow = placeholdersToShow; 21 | [self.tableView reloadData]; 22 | } 23 | 24 | - (NSString *)windowNibName { 25 | return @"HelpWindowController"; 26 | } 27 | 28 | - (void)windowDidLoad { 29 | [super windowDidLoad]; 30 | 31 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. 32 | } 33 | 34 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { 35 | return self.placeholdersToShow.count; 36 | } 37 | 38 | - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 39 | return self.placeholdersToShow[row]; 40 | } 41 | 42 | - (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard { 43 | NSString *string = self.placeholdersToShow[rowIndexes.lastIndex]; 44 | [pboard declareTypes:@[NSPasteboardTypeString] owner:self]; 45 | [pboard setString:string forType:NSPasteboardTypeString]; 46 | return true; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /PrefsPane/PrefsPane.h: -------------------------------------------------------------------------------- 1 | // 2 | // PrefsPane.h 3 | // PrefsPane 4 | // 5 | // Created by Chen Guo on 19/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "PrefsPaneDelegate.h" 12 | #import "HelpWindowController.h" 13 | 14 | @interface PrefsPane : NSPreferencePane { 15 | IBOutlet NSView *preferenceView; 16 | } 17 | 18 | @property (weak) NSObject *delegate; 19 | 20 | @property HelpWindowController *helpWindowController; 21 | 22 | @property (weak) IBOutlet NSPopUpButton *openPDFWithPopUpButton; 23 | 24 | @property (weak) IBOutlet NSTabView *tabView; 25 | 26 | @property (weak) IBOutlet NSTextField *selectionLinkPlainTextTextField; 27 | @property (weak) IBOutlet NSButton *selectionLinkRichTextSameAsPlainTextCheckBox; 28 | @property (weak) IBOutlet NSTextField *selectionLinkRichTextTextField; 29 | @property (weak) IBOutlet NSButton *showNotificationWhenFileNotFoundInDNtpForSelectionLinkCheckBox; 30 | 31 | @property (weak) IBOutlet NSTextField *selectionFilesLocationTextField; 32 | @property (weak) IBOutlet NSTextField *selectionFileNameTextField; 33 | @property (weak) IBOutlet NSTextField *selectionFileExtensionTextField; 34 | @property (weak) IBOutlet NSTextField *selectionFileTagsTextField; 35 | @property (weak) IBOutlet NSTextField *selectionFileContentTextField; 36 | @property (unsafe_unretained) IBOutlet NSButton *showNotificationWhenFileNotFoundInDNtpForSelectionFileCheckBox; 37 | 38 | @property (weak) IBOutlet NSTextField *annotationFilesLocationTextField; 39 | @property (weak) IBOutlet NSTextField *annotationFileNameTextField; 40 | @property (weak) IBOutlet NSTextField *annotationFileExtensionTextField; 41 | @property (weak) IBOutlet NSTextField *annotationFileTagsTextField; 42 | @property (weak) IBOutlet NSTextField *annotationFileContentTextField; 43 | @property (unsafe_unretained) IBOutlet NSButton *showNotificationWhenFileNotFoundInDNtpForAnnotationFileCheckBox; 44 | 45 | - (void)mainViewDidLoad; 46 | 47 | - (IBAction)openPDFWithPopUpButtonEndSelecting:(NSPopUpButton *)sender; 48 | 49 | - (IBAction)selectionLinkPlainTextTextFieldEndEditing:(NSTextFieldCell *)sender; 50 | - (IBAction)selectionLinkRichTextSameAsPlainTextCheckBoxToggled:(NSButton *)sender; 51 | - (IBAction)selectionLinkRichTextTextFieldEndEditing:(NSTextField *)sender; 52 | - (IBAction)showNotificationWhenFileNotFoundInDNtpForSelectionLinkCheckBoxToggled:(NSButton *)sender; 53 | - (IBAction)resetSelectionLinkPreferencesButtonPressed:(NSButton *)sender; 54 | 55 | - (IBAction)selectionFilesLocationTextFieldEndEditing:(NSTextField *)sender; 56 | - (IBAction)chooseSelectionFilesLocationButtonPressed:(NSButton *)sender; 57 | - (IBAction)selectionFileNameTextFieldEndEditing:(NSTextField *)sender; 58 | - (IBAction)selectionFileExtensionTextFieldEndEditing:(NSTextField *)sender; 59 | - (IBAction)selectionFileTagsTextFieldEndEditing:(NSTextField *)sender; 60 | - (IBAction)selectionFileContentTextFieldEndEditing:(NSTextField *)sender; 61 | - (IBAction)resetSelectionFilePreferencesButtonPressed:(NSButton *)sender; 62 | - (IBAction)showNotificationWhenFileNotFoundInDNtpForSelectionFileCheckBoxToggled:(NSButton *)sender; 63 | 64 | - (IBAction)annotationFilesLocationTextFieldEndEditing:(NSTextField *)sender; 65 | - (IBAction)chooseAnnotationFilesLocationButtonPressed:(NSButton *)sender; 66 | - (IBAction)annotationFileNameTextFieldEndEditing:(NSTextField *)sender; 67 | - (IBAction)annotationFileExtensionTextFieldEndEditing:(NSTextField *)sender; 68 | - (IBAction)annotationFileTagsTextFieldEndEditing:(NSTextField *)sender; 69 | - (IBAction)annotationFileContentTextFieldEndEditing:(NSTextField *)sender; 70 | - (IBAction)resetAnnotationFilePreferencesButtonPressed:(NSButton *)sender; 71 | - (IBAction)showNotificationWhenFileNotFoundInDNtpForAnnotationFileCheckBoxToggled:(NSButton *)sender; 72 | 73 | - (IBAction)helpButtonPressed:(NSButton *)sender; 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /PrefsPane/PrefsPane.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/PrefsPane/PrefsPane.tiff -------------------------------------------------------------------------------- /PrefsPane/PrefsPaneDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // PrefsPaneDelegate.h 3 | // Excerptor 4 | // 5 | // Created by Chen Guo on 23/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, PDFReaderApp) { 12 | PDFReaderAppPreview, 13 | PDFReaderAppSkim 14 | }; 15 | 16 | @protocol PrefsPaneDelegate 17 | 18 | @property (readonly) NSArray *availablePlaceholders; 19 | @property (readonly) NSArray *availableSelectionPlaceholders; 20 | @property (readonly) NSArray *availableAnnotationPlaceholders; 21 | 22 | @property (readwrite) NSString *stringForSelectionLinkPlainText; 23 | @property (readwrite) BOOL boolForSelectionLinkRichTextSameAsPlainText; 24 | @property (readwrite) NSString *stringForSelectionLinkRichText; 25 | @property (readwrite) BOOL boolForShowNotificationWhenFileNotFoundInDNtpForSelectionLink; 26 | 27 | @property (readwrite) PDFReaderApp appForOpenPDF; 28 | 29 | @property (readwrite) NSString *stringForSelectionFilesLocation; 30 | @property (readwrite) NSString *stringForSelectionFileName; 31 | @property (readwrite) NSString *stringForSelectionFileExtension; 32 | @property (readwrite) NSString *stringForSelectionFileTags; 33 | @property (readwrite) NSString *stringForSelectionFileContent; 34 | @property (readwrite) BOOL boolForShowNotificationWhenFileNotFoundInDNtpForSelectionFile; 35 | 36 | @property (readwrite) NSString *stringForAnnotationFilesLocation; 37 | @property (readwrite) NSString *stringForAnnotationFileName; 38 | @property (readwrite) NSString *stringForAnnotationFileExtension; 39 | @property (readwrite) NSString *stringForAnnotationFileTags; 40 | @property (readwrite) NSString *stringForAnnotationFileContent; 41 | @property (readwrite) BOOL boolForShowNotificationWhenFileNotFoundInDNtpForAnnotationFile; 42 | 43 | - (void)resetSelectionLinkPreferences; 44 | - (void)resetSelectionFilePreferences; 45 | - (void)resetAnnotationFilePreferences; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /PrefsPane/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.2 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 4 23 | NSHumanReadableCopyright 24 | Copyright © 2015 guoc. All rights reserved. 25 | NSMainNibFile 26 | PrefsPane 27 | NSPrefPaneIconFile 28 | PrefsPane.tiff 29 | NSPrefPaneIconLabel 30 | PrefsPane 31 | NSPrincipalClass 32 | PrefsPane 33 | 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Excerptor 2 | 3 | Quickly take and locate excerpts in PDF files. 4 | 5 | Support Preview / Skim (>= 1.4.11) in OS X / macOS (>= 10.10) 6 | 7 | Dependencies: [SIMBL](http://www.culater.net/software/SIMBL/SIMBL.php) / [mySIMBL](https://github.com/w0lfschild/mySIMBL) 8 | 9 | When you read a PDF file, you may want to take some excerpts, like excerpting on physical books (including article name, page number etc.). *Via Excerptor, you can take excerpts easily: select text in Preview/[Skim](http://skim-app.sourceforge.net) and type a shortcut. An excerpt will be stored in pasteboard or a file. The excerpt includes a special link. By clicking the link, Excerptor will open the corresponding file by Preview/Skim, go to the page you want and highlight the excerpt you made, automatically.* 10 | 11 | ![Excerpt To Pasteboard](https://github.com/guoc/excerptor/raw/master/screenshots/excerpt_to_pasteboard.gif) 12 | 13 | (In the screenshot, the link is pasted as rich text in Notes.app. It will be plain text if it is pasted in an application which only supports plain text.) 14 | 15 | ## Features 16 | 17 | ### No lock-in format. 18 | 19 | * Excerpt file format is plain text. 20 | * Excerptor links contain all information to locate excerpts. It is possible to find your excerpts by following the information in an excerpt link itself. Even if the PDF files are missing, the excerpt text could be extracted from the excerpt link per se. 21 | 22 | A typical excerpt link is as follows (The part in square brackets may be repeated and delimited by "-"). 23 | ``` 24 | excerptor://{FilePathOrDEVONthinkUUID}:{ExcerptText}:[p{PageNumber}_{ExcerptTextLocation}_{ExcerptTextLength}] 25 | ``` 26 | See Wiki page [Excerpt Link Format](https://github.com/guoc/excerptor/wiki/Excerpt-Link-Format) for details. 27 | 28 | ### Fully customizable 29 | 30 | Excerpts are generated by templates which can be set in Excerptor's preferences. 31 | 32 | ![Excerptor Preferences (Excerpt To Pasteboard)](screenshots/preferences_excerpt_to_pasteboard.png) 33 | ![Excerptor Preferences (Excerpt To File)](screenshots/preferences_excerpt_to_file.png) 34 | 35 | ## DEVONthink Pro support 36 | 37 | UUID in DEVONthink Pro can be used to locate PDF files if it is installed, otherwise file paths are used to locate files. 38 | 39 | DEVONthink's built-in PDF viewer is not supported to take excerpts. 40 | 41 | ## QuickLook excerpt files 42 | 43 | By default, excerpt files generated by Excerptor are [Markdown](http://daringfireball.net/projects/markdown/) plain text format. 44 | 45 | With Brett Terpstra's MMD-QuickLook(https://github.com/ttscoff/MMD-QuickLook/), you can QuickLook excerpt files by typing space bar when a excerpt file is selected. 46 | 47 | ![MMD-QuickLook](screenshots/mmd_quicklook.png) 48 | 49 | You can click an excerpt link in QuickLook views to open the corresponding PDF file and locate to your excerpt. 50 | 51 | ## Installation 52 | 53 | See Wiki page [Excerptor Installation for OS X 10.10 and 10.11](https://github.com/guoc/excerptor/wiki/Excerptor-Installation-for-OS-X-10.10-and-10.11) or [Excerptor Installation for macOS 10.12](https://github.com/guoc/excerptor/wiki/Excerptor-Installation-for-macOS-10.12) 54 | 55 | ## Bug report and feature request 56 | are very welcome. Create an issue or email me guochen42+excerptor@gmail.com 57 | -------------------------------------------------------------------------------- /Shared Files/AnnotationLocation.h: -------------------------------------------------------------------------------- 1 | // 2 | // AnnotationLocation.h 3 | // GoToPDFDestination 4 | // 5 | // Created by Chen Guo on 8/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Location.h" 11 | 12 | @interface AnnotationLocation : Location 13 | 14 | @property (nonatomic) NSUInteger pageIndex; 15 | @property (nonatomic) NSDate *annotationDate; 16 | 17 | - (id)initWithPDFFilePath:(NSString *)pdfFilePath pageIndex:(NSUInteger)pageIndex annotationDate:(NSDate *)annotationDate; 18 | - (id)initWithCoder:(NSCoder *)aDecoder; 19 | - (void)encodeWithCoder:(NSCoder *)aCoder; 20 | 21 | - (BOOL)locateByWindowController:(NSWindowController *)windowController; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Shared Files/AnnotationLocation.m: -------------------------------------------------------------------------------- 1 | // 2 | // AnnotationLocation.m 3 | // GoToPDFDestination 4 | // 5 | // Created by Chen Guo on 8/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Preview.h" 11 | #import "Skim.h" 12 | #import "AnnotationLocation.h" 13 | 14 | @implementation AnnotationLocation 15 | 16 | @synthesize pageIndex = _pageIndex; 17 | @synthesize annotationDate = _annotationDate; 18 | 19 | - (id)initWithPDFFilePath:(NSString *)pdfFilePath pageIndex:(NSUInteger)pageIndex annotationDate:(NSDate *)annotationDate { 20 | self = [super init]; 21 | if (!self) { 22 | return nil; 23 | } 24 | 25 | self.pdfFilePath = pdfFilePath; 26 | self.pageIndex = pageIndex; 27 | self.annotationDate = annotationDate; 28 | 29 | return self; 30 | } 31 | 32 | - (BOOL)locateByWindowController:(NSWindowController *)windowController { 33 | id pdfView = [windowController performSelector:@selector(pdfView)]; 34 | PDFPage *page = [[pdfView document] pageAtIndex:self.pageIndex]; 35 | if (!self.annotationDate) { 36 | [pdfView goToPage:page]; 37 | return YES; 38 | } 39 | 40 | if ([pdfView isKindOfClass:NSClassFromString(@"PVPDFView")]) { 41 | NSArray *annotations = floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12 ? [pdfView annotations] : [page annotations]; 42 | PVAnnotation *annotation; 43 | for (annotation in annotations) { 44 | NSDate *date = floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12 ? [annotation date] : [annotation modificationDate]; 45 | if ([date isEqualToDate:self.annotationDate]) { 46 | break; 47 | } 48 | } 49 | if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { 50 | if ([[annotation date] isEqualToDate:self.annotationDate]) { 51 | CGRect rect = [annotation bounds]; 52 | [pdfView goToRect:rect onPage:page]; 53 | 54 | BOOL modifyingExistingSelection = NO; 55 | NSMethodSignature* signature = [[pdfView class] instanceMethodSignatureForSelector: @selector( selectAnnotation: byModifyingExistingSelection: )]; 56 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: signature]; 57 | [invocation setTarget: pdfView]; 58 | [invocation setSelector: @selector( selectAnnotation: byModifyingExistingSelection: )]; 59 | [invocation setArgument: &annotation atIndex: 2]; 60 | [invocation setArgument: &modifyingExistingSelection atIndex: 3]; 61 | [invocation invoke]; 62 | return YES; 63 | } 64 | } else { 65 | [pdfView goToRect:[annotation bounds] onPage:[annotation page]]; 66 | } 67 | 68 | return NO; 69 | } else { // PDFAnnotation 70 | for (PDFAnnotation *annotation in [page annotations]) { 71 | if ([[annotation modificationDate] isEqualToDate:self.annotationDate]) { 72 | [pdfView scrollAnnotationToVisible:annotation]; 73 | [pdfView setActiveAnnotation:annotation]; 74 | return YES; 75 | } 76 | } 77 | return NO; 78 | } 79 | } 80 | 81 | - (id)initWithCoder:(NSCoder *)aDecoder { 82 | self = [super init]; 83 | if (!self) { 84 | return nil; 85 | } 86 | 87 | self.pdfFilePath = [aDecoder decodeObjectForKey:@"pdfFilePath"]; 88 | self.pageIndex = [aDecoder decodeIntegerForKey:@"pageIndex"]; 89 | self.annotationDate = [aDecoder decodeObjectForKey:@"annotationDate"]; 90 | 91 | return self; 92 | } 93 | 94 | - (void)encodeWithCoder:(NSCoder *)aCoder { 95 | [aCoder encodeObject:self.pdfFilePath forKey:@"pdfFilePath"]; 96 | [aCoder encodeInteger:self.pageIndex forKey:@"pageIndex"]; 97 | [aCoder encodeObject:self.annotationDate forKey:@"annotationDate"]; 98 | } 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /Shared Files/Location.h: -------------------------------------------------------------------------------- 1 | // 2 | // Location.h 3 | // GoToPDFDestination 4 | // 5 | // Created by Chen Guo on 9/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Preview.h" 11 | 12 | @interface Location : NSObject 13 | 14 | @property (nonatomic) NSString *pdfFilePath; 15 | - (BOOL)locateByWindowController: (NSWindowController *)windowController; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Shared Files/Location.m: -------------------------------------------------------------------------------- 1 | // 2 | // Location.m 3 | // GoToPDFDestination 4 | // 5 | // Created by Chen Guo on 9/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import "Location.h" 10 | 11 | @implementation Location 12 | 13 | @synthesize pdfFilePath = _pdfFilePath; 14 | 15 | - (BOOL)locateByWindowController: (NSWindowController *)windowController { 16 | return NO; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Shared Files/Preview.h: -------------------------------------------------------------------------------- 1 | // 2 | // Preview.h 3 | // PDFReaderPlugin 4 | // 5 | // Created by Chen Guo on 15/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #ifndef PDFReaderPlugin_Preview_h 10 | #define PDFReaderPlugin_Preview_h 11 | 12 | @import Quartz; 13 | 14 | @interface PVAnnotation : PDFAnnotation 15 | 16 | @property(retain) NSDate *date; 17 | @property struct CGRect bounds; 18 | 19 | @end 20 | 21 | 22 | @interface PVPDFView : PDFView 23 | 24 | - (id)annotations; 25 | - (void)selectAnnotation:(id)arg1 byModifyingExistingSelection:(BOOL)arg2; 26 | 27 | @end 28 | 29 | 30 | @interface PVMediaContainerBase : NSDocument 31 | 32 | @end 33 | 34 | 35 | @interface PVPDFPageContainer : PVMediaContainerBase 36 | 37 | @property(retain) PDFDocument *pdfDocument; // @synthesize pdfDocument=_pdfDocument; 38 | 39 | @end 40 | 41 | 42 | @interface PVWindowController : NSWindowController 43 | 44 | @property(readonly) PVPDFView *pdfView; 45 | 46 | @end 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /Shared Files/SelectionLineLocation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SelectionLineLocation.h 3 | // GoToPDFDestination 4 | // 5 | // Created by Chen Guo on 7/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SelectionLineLocation : NSObject 12 | 13 | @property (nonatomic) NSString *string; 14 | @property (nonatomic) NSUInteger pageIndex; 15 | @property (nonatomic) NSRect bound; 16 | @property (nonatomic) NSRange range; 17 | 18 | - (instancetype)initWithString:(NSString *)string pageIndex:(NSUInteger)pageIndex range:(NSRange)range bound:(NSRect)bound; 19 | - (id)initWithCoder:(NSCoder *)aDecoder; 20 | - (void)encodeWithCoder:(NSCoder *)aCoder; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Shared Files/SelectionLineLocation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SelectionLineLocation.m 3 | // GoToPDFDestination 4 | // 5 | // Created by Chen Guo on 7/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import "SelectionLineLocation.h" 10 | 11 | @implementation SelectionLineLocation 12 | 13 | @synthesize string = _string; 14 | @synthesize pageIndex = _pageIndex; 15 | @synthesize bound = _bound; 16 | @synthesize range = _range; 17 | 18 | - (instancetype)initWithString:(NSString *)string pageIndex:(NSUInteger)pageIndex range:(NSRange)range bound:(NSRect)bound { 19 | self = [super init]; 20 | if (!self) { 21 | return nil; 22 | } 23 | 24 | self.string = string; 25 | self.pageIndex = pageIndex; 26 | self.bound = bound; 27 | self.range = range; 28 | 29 | return self; 30 | } 31 | 32 | - (id)initWithCoder:(NSCoder *)aDecoder { 33 | self = [super init]; 34 | if (!self) { 35 | return nil; 36 | } 37 | 38 | self.string = [aDecoder decodeObjectForKey:@"string"]; 39 | self.pageIndex = [aDecoder decodeIntegerForKey:@"pageIndex"]; 40 | self.bound = [[aDecoder decodeObjectForKey:@"bound"] rectValue]; 41 | self.range = [[aDecoder decodeObjectForKey:@"range"] rangeValue]; 42 | 43 | return self; 44 | } 45 | 46 | - (void)encodeWithCoder:(NSCoder *)aCoder { 47 | [aCoder encodeObject:self.string forKey:@"string"]; 48 | [aCoder encodeInteger:self.pageIndex forKey:@"pageIndex"]; 49 | [aCoder encodeObject:[NSValue valueWithRect:self.bound] forKey:@"bound"]; 50 | [aCoder encodeObject:[NSValue valueWithRange:self.range] forKey:@"range"]; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Shared Files/SelectionLocation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SelectionLocation.h 3 | // GoToPDFDestination 4 | // 5 | // Created by Chen Guo on 7/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Location.h" 11 | 12 | @interface SelectionLocation : Location 13 | 14 | @property (nonatomic) NSArray *selectionLineLocations; 15 | 16 | - (instancetype)initWithPDFFilePath:(NSString *)filePath selectionLineLocations:(NSArray *)selectionLineLocations; 17 | - (id)initWithCoder:(NSCoder *)aDecoder; 18 | - (void)encodeWithCoder:(NSCoder *)aCoder; 19 | 20 | - (BOOL)locateByWindowController: (NSWindowController *)windowController; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Shared Files/SelectionLocation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SelectionLocation.m 3 | // GoToPDFDestination 4 | // 5 | // Created by Chen Guo on 7/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Preview.h" 11 | #import "SelectionLocation.h" 12 | #import "SelectionLineLocation.h" 13 | 14 | @implementation SelectionLocation 15 | 16 | @synthesize selectionLineLocations = _selectionLineLocations; 17 | 18 | - (instancetype)initWithPDFFilePath:(NSString *)filePath selectionLineLocations:(NSArray *)selectionLineLocations { 19 | self = [super init]; 20 | if (!self) { 21 | return nil; 22 | } 23 | 24 | self.pdfFilePath = filePath; 25 | self.selectionLineLocations = selectionLineLocations; 26 | 27 | return self; 28 | } 29 | 30 | - (BOOL)locateByWindowController: (NSWindowController *)windowController { 31 | id pdfView = [windowController performSelector:@selector(pdfView)]; 32 | PDFDocument *pdfDocument = nil; 33 | id windowDocument = [windowController document]; 34 | if ([windowDocument isKindOfClass:[NSClassFromString(@"PVPDFPageContainer") class]] || [windowDocument isKindOfClass:[NSClassFromString(@"SKMainDocument") class]]) { 35 | pdfDocument = [windowDocument pdfDocument]; 36 | } else { 37 | NSLog(@"Unexpected PDF document"); 38 | return NO; 39 | } 40 | 41 | PDFSelection *selectionToHighlight = [[PDFSelection alloc] initWithDocument:pdfDocument]; 42 | for (SelectionLineLocation *selectionLineLocation in self.selectionLineLocations) { 43 | NSUInteger pageIndex = selectionLineLocation.pageIndex; 44 | PDFPage *page = [pdfDocument pageAtIndex:pageIndex]; 45 | NSRange pageStringRange = NSMakeRange(0, page.string.length - 1); 46 | NSRange range = NSIntersectionRange(selectionLineLocation.range, pageStringRange); 47 | PDFSelection *selection = [page selectionForRange:range]; 48 | [selectionToHighlight addSelection:selection]; 49 | } 50 | [pdfView performSelector:@selector(setCurrentSelection:) withObject: selectionToHighlight]; 51 | [pdfView performSelector:@selector(goToSelection:) withObject: selectionToHighlight]; 52 | return YES; 53 | } 54 | 55 | 56 | - (id)initWithCoder:(NSCoder *)aDecoder { 57 | self = [super init]; 58 | if (!self) { 59 | return nil; 60 | } 61 | 62 | self.pdfFilePath = [aDecoder decodeObjectForKey:@"pdfFilePath"]; 63 | self.selectionLineLocations = [aDecoder decodeObjectForKey:@"selectionLineLocations"]; 64 | 65 | return self; 66 | } 67 | 68 | - (void)encodeWithCoder:(NSCoder *)aCoder { 69 | [aCoder encodeObject:self.pdfFilePath forKey:@"pdfFilePath"]; 70 | [aCoder encodeObject:self.selectionLineLocations forKey:@"selectionLineLocations"]; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Shared Files/Skim.h: -------------------------------------------------------------------------------- 1 | // 2 | // Skim.h 3 | // PDFReaderPlugin 4 | // 5 | // Created by Chen Guo on 16/05/2015. 6 | // Copyright (c) 2015 guoc. All rights reserved. 7 | // 8 | 9 | #ifndef PDFReaderPlugin_Skim_h 10 | #define PDFReaderPlugin_Skim_h 11 | 12 | @interface SKPDFView : PDFView 13 | 14 | - (void)scrollAnnotationToVisible:(PDFAnnotation *)annotation; 15 | - (void)setActiveAnnotation:(PDFAnnotation *)newAnnotation; 16 | 17 | @end 18 | 19 | 20 | @interface SKMainDocument : NSDocument 21 | 22 | @property (nonatomic, readonly) PDFDocument *pdfDocument; 23 | 24 | @end 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /screenshots/excerpt_to_pasteboard.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/screenshots/excerpt_to_pasteboard.gif -------------------------------------------------------------------------------- /screenshots/mmd_quicklook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/screenshots/mmd_quicklook.png -------------------------------------------------------------------------------- /screenshots/preferences_excerpt_to_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/screenshots/preferences_excerpt_to_file.png -------------------------------------------------------------------------------- /screenshots/preferences_excerpt_to_pasteboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guoc/excerptor/0ebd858757c84c6679e92b204014ffa353326f34/screenshots/preferences_excerpt_to_pasteboard.png --------------------------------------------------------------------------------