├── .gitignore ├── COPYING ├── Configurations ├── Base.xcconfig └── Version.xcconfig ├── DiffMatchPatch.h ├── DiffMatchPatch.m ├── DiffMatchPatch.xcodeproj └── project.pbxproj ├── DiffMatchPatchCFUtilities.c ├── DiffMatchPatchCFUtilities.h ├── DiffMatchPatch_Prefix.pch ├── Google-diff-Match-Patch.podspec ├── Info.plist ├── JXArcCompatibilityMacros.h ├── MinMaxMacros.h ├── NSMutableDictionary+DMPExtensions.h ├── NSMutableDictionary+DMPExtensions.m ├── NSString+JavaSubstring.h ├── NSString+JavaSubstring.m ├── NSString+UnicharUtilities.h ├── NSString+UnicharUtilities.m ├── NSString+UriCompatibility.h ├── NSString+UriCompatibility.m ├── README.markdown ├── Speedtest1.txt ├── Speedtest2.txt ├── Tests ├── DiffMatchPatchTest-Info.plist ├── DiffMatchPatchTest.h ├── DiffMatchPatchTest.m ├── TestUtilities.h ├── TestUtilities.m ├── mode-test.m └── speedtest.m ├── en.lproj └── InfoPlist.strings └── speedtest_Prefix.pch /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | 17 | ## Ignore incredibly annoying .DS_Store files 18 | .DS_Store 19 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | -------------------------------------------------------------------------------- /Configurations/Base.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Version.xcconfig" 2 | 3 | //SDKROOT = macosx10.7 4 | MACOSX_DEPLOYMENT_TARGET = 10.6 5 | PREBINDING = NO 6 | 7 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0 8 | GCC_C_LANGUAGE_STANDARD = gnu99 9 | 10 | GCC_WARN_CHECK_SWITCH_STATEMENTS = YES 11 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO 12 | GCC_WARN_SHADOW = YES 13 | GCC_TREAT_WARNINGS_AS_ERRORS = YES 14 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES 15 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES 16 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES 17 | GCC_WARN_ABOUT_RETURN_TYPE = YES 18 | GCC_WARN_MISSING_PARENTHESES = YES 19 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES 20 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES 21 | GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES 22 | GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES 23 | GCC_WARN_SIGN_COMPARE = YES 24 | GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES 25 | GCC_WARN_UNDECLARED_SELECTOR = YES 26 | GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES 27 | GCC_WARN_UNINITIALIZED_AUTOS = YES 28 | GCC_WARN_UNKNOWN_PRAGMAS = YES 29 | GCC_WARN_UNUSED_FUNCTION = YES 30 | GCC_WARN_UNUSED_LABEL = YES 31 | GCC_WARN_UNUSED_PARAMETER = NO 32 | GCC_WARN_UNUSED_VALUE = YES 33 | GCC_WARN_UNUSED_VARIABLE = YES 34 | 35 | -------------------------------------------------------------------------------- /Configurations/Version.xcconfig: -------------------------------------------------------------------------------- 1 | MARKETING_VERSION = 1.0.6 2 | PROJECT_VERSION = 1000 3 | -------------------------------------------------------------------------------- /DiffMatchPatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import 24 | 25 | /* 26 | * Functions for diff, match and patch. 27 | * Computes the difference between two texts to create a patch. 28 | * Applies the patch onto another text, allowing for errors. 29 | */ 30 | 31 | /* 32 | * The data structure representing a diff is an NSMutableArray of Diff objects: 33 | * {Diff(Operation.DIFF_DELETE, "Hello"), 34 | * Diff(Operation.DIFF_INSERT, "Goodbye"), 35 | * Diff(Operation.DIFF_EQUAL, " world.")} 36 | * which means: delete "Hello", add "Goodbye" and keep " world." 37 | */ 38 | 39 | typedef enum { 40 | DIFF_DELETE = 1, 41 | DIFF_INSERT = 2, 42 | DIFF_EQUAL = 3 43 | } Operation; 44 | 45 | typedef enum { 46 | DiffWordTokens = 1, 47 | DiffParagraphTokens = 2, 48 | DiffSentenceTokens = 3, 49 | DiffLineBreakDelimiteredTokens = 4 50 | } DiffTokenMode; 51 | 52 | /* 53 | * Class representing one diff operation. 54 | */ 55 | @interface Diff : NSObject { 56 | Operation operation; // One of: DIFF_INSERT, DIFF_DELETE or DIFF_EQUAL. 57 | NSString *text; // The text associated with this diff operation. 58 | } 59 | 60 | @property (nonatomic, assign) Operation operation; 61 | @property (nonatomic, copy) NSString *text; 62 | 63 | + (id)diffWithOperation:(Operation)anOperation andText:(NSString *)aText; 64 | 65 | - (id)initWithOperation:(Operation)anOperation andText:(NSString *)aText; 66 | 67 | @end 68 | 69 | /* 70 | * Class representing one patch operation. 71 | */ 72 | @interface Patch : NSObject { 73 | NSMutableArray *diffs; 74 | NSUInteger start1; 75 | NSUInteger start2; 76 | NSUInteger length1; 77 | NSUInteger length2; 78 | } 79 | 80 | @property (nonatomic, strong) NSMutableArray *diffs; 81 | @property (nonatomic, assign) NSUInteger start1; 82 | @property (nonatomic, assign) NSUInteger start2; 83 | @property (nonatomic, assign) NSUInteger length1; 84 | @property (nonatomic, assign) NSUInteger length2; 85 | 86 | @end 87 | 88 | #ifndef NS_RETURNS_RETAINED 89 | #if __has_feature(attribute_ns_returns_retained) 90 | #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) 91 | #else 92 | #define NS_RETURNS_RETAINED 93 | #endif 94 | #endif 95 | 96 | /* 97 | * Class containing the diff, match and patch methods. 98 | * Also Contains the behaviour settings. 99 | */ 100 | @interface DiffMatchPatch : NSObject { 101 | // Number of seconds to map a diff before giving up (0 for infinity). 102 | NSTimeInterval Diff_Timeout; 103 | 104 | // Cost of an empty edit operation in terms of edit characters. 105 | NSUInteger Diff_EditCost; 106 | 107 | // At what point is no match declared (0.0 = perfection, 1.0 = very loose). 108 | double Match_Threshold; 109 | 110 | // How far to search for a match (0 = exact location, 1000+ = broad match). 111 | // A match this many characters away from the expected location will add 112 | // 1.0 to the score (0.0 is a perfect match). 113 | NSInteger Match_Distance; 114 | 115 | // When deleting a large block of text (over ~64 characters), how close 116 | // do the contents have to be to match the expected contents. (0.0 = 117 | // perfection, 1.0 = very loose). Note that Match_Threshold controls 118 | // how closely the end points of a delete need to match. 119 | float Patch_DeleteThreshold; 120 | 121 | // Chunk size for context length. 122 | uint16_t Patch_Margin; 123 | 124 | // The number of bits in an int. 125 | NSUInteger Match_MaxBits; 126 | } 127 | 128 | @property (nonatomic, assign) NSTimeInterval Diff_Timeout; 129 | @property (nonatomic, assign) NSUInteger Diff_EditCost; 130 | @property (nonatomic, assign) double Match_Threshold; 131 | @property (nonatomic, assign) NSInteger Match_Distance; 132 | @property (nonatomic, assign) float Patch_DeleteThreshold; 133 | @property (nonatomic, assign) uint16_t Patch_Margin; 134 | 135 | - (NSMutableArray *)diff_mainOfOldString:(NSString *)text1 andNewString:(NSString *)text2; 136 | - (NSMutableArray *)diff_mainOfOldString:(NSString *)text1 andNewString:(NSString *)text2 checkLines:(BOOL)checklines; 137 | - (NSUInteger)diff_commonPrefixOfFirstString:(NSString *)text1 andSecondString:(NSString *)text2; 138 | - (NSUInteger)diff_commonSuffixOfFirstString:(NSString *)text1 andSecondString:(NSString *)text2; 139 | - (void)diff_cleanupSemantic:(NSMutableArray *)diffs; 140 | - (void)diff_cleanupSemanticLossless:(NSMutableArray *)diffs; 141 | - (void)diff_cleanupEfficiency:(NSMutableArray *)diffs; 142 | - (void)diff_cleanupMerge:(NSMutableArray *)diffs; 143 | - (NSUInteger)diff_xIndexIn:(NSMutableArray *)diffs location:(NSUInteger) loc; 144 | - (NSString *)diff_prettyHtml:(NSMutableArray *)diffs; 145 | - (NSString *)diff_text1:(NSMutableArray *)diffs; 146 | - (NSString *)diff_text2:(NSMutableArray *)diffs; 147 | - (NSUInteger)diff_levenshtein:(NSArray *)diffs; 148 | - (NSString *)diff_toDelta:(NSMutableArray *)diffs; 149 | - (NSMutableArray *)diff_fromDeltaWithText:(NSString *)text1 andDelta:(NSString *)delta error:(NSError **)error; 150 | 151 | - (NSUInteger)match_mainForText:(NSString *)text pattern:(NSString *)pattern near:(NSUInteger)loc; 152 | - (NSMutableDictionary *)match_alphabet:(NSString *)pattern; 153 | 154 | - (NSMutableArray *)patch_makeFromOldString:(NSString *)text1 andNewString:(NSString *)text2; 155 | - (NSMutableArray *)patch_makeFromDiffs:(NSMutableArray *)diffs; 156 | - (NSMutableArray *)patch_makeFromOldString:(NSString *)text1 newString:(NSString *)text2 diffs:(NSMutableArray *)diffs; 157 | - (NSMutableArray *)patch_makeFromOldString:(NSString *)text1 andDiffs:(NSMutableArray *)diffs; 158 | - (NSMutableArray *)patch_deepCopy:(NSArray *)patches NS_RETURNS_RETAINED; // Copy rule applies! 159 | - (NSArray *)patch_apply:(NSArray *)sourcePatches toString:(NSString *)text; 160 | - (NSString *)patch_addPadding:(NSMutableArray *)patches; 161 | - (void)patch_splitMax:(NSMutableArray *)patches; 162 | - (NSString *)patch_toText:(NSMutableArray *)patches; 163 | - (NSMutableArray *)patch_fromText:(NSString *)textline error:(NSError **)error; 164 | 165 | @end 166 | 167 | 168 | @interface DiffMatchPatch (PrivateMethods) 169 | 170 | + (CFOptionFlags)tokenizerOptionsForMode:(DiffTokenMode)mode; 171 | 172 | - (NSMutableArray *)diff_mainOfOldString:(NSString *)text1 andNewString:(NSString *)text2 checkLines:(BOOL)checklines deadline:(NSTimeInterval)deadline; 173 | - (NSMutableArray *)diff_computeFromOldString:(NSString *)text1 andNewString:(NSString *)text2 checkLines:(BOOL)checklines deadline:(NSTimeInterval)deadline; 174 | - (NSMutableArray *)diff_lineModeFromOldString:(NSString *)text1 andNewString:(NSString *)text2 deadline:(NSTimeInterval)deadline; 175 | - (NSArray *)diff_linesToCharsForFirstString:(NSString *)text1 andSecondString:(NSString *)text1; 176 | - (NSArray *)diff_tokensToCharsForFirstString:(NSString *)text1 andSecondString:(NSString *)text2 mode:(DiffTokenMode)mode; 177 | - (NSArray *)diff_wordsToCharsForFirstString:(NSString *)text1 andSecondString:(NSString *)text1; 178 | - (NSString *)diff_linesToCharsMungeOfText:(NSString *)text lineArray:(NSMutableArray *)lineArray lineHash:(NSMutableDictionary *)lineHash; 179 | - (NSString *)diff_wordsToCharsMungeOfText:(NSString *)text wordArray:(NSMutableArray *)wordArray wordHash:(NSMutableDictionary *)wordHash; 180 | - (NSString *)diff_sentencesToCharsMungeOfText:(NSString *)text sentenceArray:(NSMutableArray *)sentenceArray sentenceHash:(NSMutableDictionary *)sentenceHash; 181 | - (NSString *)diff_paragraphsToCharsMungeOfText:(NSString *)text paragraphArray:(NSMutableArray *)paragraphArray paragraphHash:(NSMutableDictionary *)paragraphHash; 182 | - (NSString *)diff_lineBreakDelimiteredToCharsMungeOfText:(NSString *)text lineArray:(NSMutableArray *)lineArray lineHash:(NSMutableDictionary *)lineHash; 183 | - (NSString *)diff_charsToTokenString:(NSString *)charsString usingTokens:(NSArray *)tokenArray; 184 | - (void)diff_chars:(NSArray *)diffs toLines:(NSArray *)lineArray; 185 | - (void)diff_chars:(NSArray *)diffs toTokens:(NSArray *)tokenArray; 186 | - (NSMutableArray *)diff_bisectOfOldString:(NSString *)text1 andNewString:(NSString *)text2 deadline:(NSTimeInterval)deadline; 187 | - (NSMutableArray *)diff_bisectSplitOfOldString:(NSString *)text1 andNewString:(NSString *)text2 x:(NSUInteger)x y:(NSUInteger)y deadline:(NSTimeInterval)deadline; 188 | - (NSUInteger)diff_commonOverlapOfFirstString:(NSString *)text1 andSecondString:(NSString *)text2; 189 | - (NSArray *)diff_halfMatchOfFirstString:(NSString *)text1 andSecondString:(NSString *)text2; 190 | - (NSArray *)diff_halfMatchIOfLongString:(NSString *)longtext andShortString:(NSString *)shorttext; 191 | - (NSInteger)diff_cleanupSemanticScoreOfFirstString:(NSString *)one andSecondString:(NSString *)two; 192 | 193 | - (NSUInteger)match_bitapOfText:(NSString *)text andPattern:(NSString *)pattern near:(NSUInteger)loc; 194 | - (double)match_bitapScoreForErrorCount:(NSUInteger)e location:(NSUInteger)x near:(NSUInteger)loc pattern:(NSString *)pattern; 195 | 196 | - (void)patch_addContextToPatch:(Patch *)patch sourceText:(NSString *)text; 197 | 198 | @end 199 | -------------------------------------------------------------------------------- /DiffMatchPatch.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3D03489B135F75770051FE16 /* mode-test.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D03489A135F75770051FE16 /* mode-test.m */; }; 11 | 3D0348CA135F7AEC0051FE16 /* DiffMatchPatch.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* DiffMatchPatch.framework */; }; 12 | 3D0348CB135F7AEC0051FE16 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; 13 | 3D08D25412A71B9C007A5316 /* NSString+UnicharUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D08D25212A71B9C007A5316 /* NSString+UnicharUtilities.m */; }; 14 | 3D0D3FAB128CBD350093B0C7 /* DiffMatchPatch.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* DiffMatchPatch.framework */; }; 15 | 3D5BBFDF128C416900B8F5FF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; 16 | 3D5BC080128C44A700B8F5FF /* DiffMatchPatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D5BC07E128C44A700B8F5FF /* DiffMatchPatch.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | 3D5BC081128C44A700B8F5FF /* DiffMatchPatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D5BC07F128C44A700B8F5FF /* DiffMatchPatch.m */; }; 18 | 3D70BCC9128EDAF80078D1A6 /* NSString+UriCompatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D70BCC7128EDAF80078D1A6 /* NSString+UriCompatibility.m */; }; 19 | 3D96F3BC12AFC6D800C3E5C0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; }; 20 | 3D96F44A12AFC82F00C3E5C0 /* speedtest.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D96F44912AFC82F00C3E5C0 /* speedtest.m */; }; 21 | 3D96F44F12AFC96A00C3E5C0 /* DiffMatchPatch.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* DiffMatchPatch.framework */; }; 22 | 3DA641D1128DE21D00B33CE9 /* DiffMatchPatchCFUtilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 3DA64170128DDA3400B33CE9 /* DiffMatchPatchCFUtilities.c */; }; 23 | 3DA64278128DE8C900B33CE9 /* DiffMatchPatchTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D5BC0DE128CAAE400B8F5FF /* DiffMatchPatchTest.m */; }; 24 | 3DC87026129FF4B6001F602B /* NSString+JavaSubstring.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DC87024129FF4B6001F602B /* NSString+JavaSubstring.m */; }; 25 | 3DDD039D15F7BBFA00EF6F80 /* DiffMatchPatchCFUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DA6416F128DDA3400B33CE9 /* DiffMatchPatchCFUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26 | 3DEE4C73129D484D00885485 /* NSMutableDictionary+DMPExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DEE4C71129D484D00885485 /* NSMutableDictionary+DMPExtensions.m */; }; 27 | 3DFF2F3813C2105300DC564A /* TestUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DFF2F3713C2105300DC564A /* TestUtilities.m */; }; 28 | 3DFF2F3913C2105300DC564A /* TestUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DFF2F3713C2105300DC564A /* TestUtilities.m */; }; 29 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXContainerItemProxy section */ 33 | 3D0348CC135F7B020051FE16 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 8DC2EF4F0486A6940098B216; 38 | remoteInfo = DiffMatchPatch; 39 | }; 40 | 3D96F3B812AFC6CD00C3E5C0 /* PBXContainerItemProxy */ = { 41 | isa = PBXContainerItemProxy; 42 | containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; 43 | proxyType = 1; 44 | remoteGlobalIDString = 8DC2EF4F0486A6940098B216; 45 | remoteInfo = DiffMatchPatch; 46 | }; 47 | 3DA64279128DE8CD00B33CE9 /* PBXContainerItemProxy */ = { 48 | isa = PBXContainerItemProxy; 49 | containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; 50 | proxyType = 1; 51 | remoteGlobalIDString = 8DC2EF4F0486A6940098B216; 52 | remoteInfo = DiffMatchPatch; 53 | }; 54 | /* End PBXContainerItemProxy section */ 55 | 56 | /* Begin PBXFileReference section */ 57 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 58 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 59 | 32DBCF5E0370ADEE00C91783 /* DiffMatchPatch_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiffMatchPatch_Prefix.pch; sourceTree = ""; }; 60 | 3D03488E135F75460051FE16 /* mode-test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "mode-test"; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | 3D03489A135F75770051FE16 /* mode-test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "mode-test.m"; sourceTree = ""; }; 62 | 3D08D25112A71B9C007A5316 /* NSString+UnicharUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+UnicharUtilities.h"; sourceTree = ""; }; 63 | 3D08D25212A71B9C007A5316 /* NSString+UnicharUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+UnicharUtilities.m"; sourceTree = ""; }; 64 | 3D510E1012BEBA44008C7CE7 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = ""; }; 65 | 3D510E1112BEBA44008C7CE7 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = ""; }; 66 | 3D5BC07E128C44A700B8F5FF /* DiffMatchPatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiffMatchPatch.h; sourceTree = ""; }; 67 | 3D5BC07F128C44A700B8F5FF /* DiffMatchPatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DiffMatchPatch.m; sourceTree = ""; }; 68 | 3D5BC0AF128CA8E200B8F5FF /* DiffMatchPatchTest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DiffMatchPatchTest.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | 3D5BC0B0128CA8E200B8F5FF /* DiffMatchPatchTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DiffMatchPatchTest-Info.plist"; sourceTree = ""; }; 70 | 3D5BC0DD128CAAE400B8F5FF /* DiffMatchPatchTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiffMatchPatchTest.h; sourceTree = ""; }; 71 | 3D5BC0DE128CAAE400B8F5FF /* DiffMatchPatchTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DiffMatchPatchTest.m; sourceTree = ""; }; 72 | 3D70BCC6128EDAF80078D1A6 /* NSString+UriCompatibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+UriCompatibility.h"; sourceTree = ""; }; 73 | 3D70BCC7128EDAF80078D1A6 /* NSString+UriCompatibility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+UriCompatibility.m"; sourceTree = ""; }; 74 | 3D96F3A212AFC68900C3E5C0 /* speedtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = speedtest; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | 3D96F43E12AFC76600C3E5C0 /* speedtest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = speedtest_Prefix.pch; path = ../speedtest_Prefix.pch; sourceTree = ""; }; 76 | 3D96F44912AFC82F00C3E5C0 /* speedtest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = speedtest.m; sourceTree = ""; }; 77 | 3DA6416F128DDA3400B33CE9 /* DiffMatchPatchCFUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiffMatchPatchCFUtilities.h; sourceTree = ""; }; 78 | 3DA64170128DDA3400B33CE9 /* DiffMatchPatchCFUtilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = DiffMatchPatchCFUtilities.c; sourceTree = ""; }; 79 | 3DA642BC128DEF4900B33CE9 /* MinMaxMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MinMaxMacros.h; sourceTree = ""; }; 80 | 3DC87023129FF4B6001F602B /* NSString+JavaSubstring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+JavaSubstring.h"; sourceTree = ""; }; 81 | 3DC87024129FF4B6001F602B /* NSString+JavaSubstring.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+JavaSubstring.m"; sourceTree = ""; }; 82 | 3DEB56D916DBA4C300D11FA5 /* JXArcCompatibilityMacros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JXArcCompatibilityMacros.h; sourceTree = ""; }; 83 | 3DEE4C70129D484D00885485 /* NSMutableDictionary+DMPExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableDictionary+DMPExtensions.h"; sourceTree = ""; }; 84 | 3DEE4C71129D484D00885485 /* NSMutableDictionary+DMPExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableDictionary+DMPExtensions.m"; sourceTree = ""; }; 85 | 3DFF2F3613C2105300DC564A /* TestUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestUtilities.h; sourceTree = ""; }; 86 | 3DFF2F3713C2105300DC564A /* TestUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestUtilities.m; sourceTree = ""; }; 87 | 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 88 | 8DC2EF5B0486A6940098B216 /* DiffMatchPatch.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DiffMatchPatch.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 89 | D7DC14552572BF0F00CF8E50 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 90 | /* End PBXFileReference section */ 91 | 92 | /* Begin PBXFrameworksBuildPhase section */ 93 | 3D03488C135F75460051FE16 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | 3D0348CA135F7AEC0051FE16 /* DiffMatchPatch.framework in Frameworks */, 98 | 3D0348CB135F7AEC0051FE16 /* Foundation.framework in Frameworks */, 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | 3D5BC0AC128CA8E200B8F5FF /* Frameworks */ = { 103 | isa = PBXFrameworksBuildPhase; 104 | buildActionMask = 2147483647; 105 | files = ( 106 | 3D0D3FAB128CBD350093B0C7 /* DiffMatchPatch.framework in Frameworks */, 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | 3D96F3A012AFC68900C3E5C0 /* Frameworks */ = { 111 | isa = PBXFrameworksBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | 3D96F44F12AFC96A00C3E5C0 /* DiffMatchPatch.framework in Frameworks */, 115 | 3D96F3BC12AFC6D800C3E5C0 /* Foundation.framework in Frameworks */, 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | 8DC2EF560486A6940098B216 /* Frameworks */ = { 120 | isa = PBXFrameworksBuildPhase; 121 | buildActionMask = 2147483647; 122 | files = ( 123 | 3D5BBFDF128C416900B8F5FF /* Foundation.framework in Frameworks */, 124 | ); 125 | runOnlyForDeploymentPostprocessing = 0; 126 | }; 127 | /* End PBXFrameworksBuildPhase section */ 128 | 129 | /* Begin PBXGroup section */ 130 | 034768DFFF38A50411DB9C8B /* Products */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 8DC2EF5B0486A6940098B216 /* DiffMatchPatch.framework */, 134 | 3D5BC0AF128CA8E200B8F5FF /* DiffMatchPatchTest.xctest */, 135 | 3D96F3A212AFC68900C3E5C0 /* speedtest */, 136 | 3D03488E135F75460051FE16 /* mode-test */, 137 | ); 138 | name = Products; 139 | sourceTree = ""; 140 | }; 141 | 0867D691FE84028FC02AAC07 /* DiffMatchPatch */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 08FB77AEFE84172EC02AAC07 /* Classes */, 145 | 32C88DFF0371C24200C91783 /* Other Sources */, 146 | 089C1665FE841158C02AAC07 /* Resources */, 147 | 3D510E0F12BEBA44008C7CE7 /* Configurations */, 148 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 149 | 3D5BC0D9128CAA7600B8F5FF /* Tests */, 150 | 034768DFFF38A50411DB9C8B /* Products */, 151 | ); 152 | name = DiffMatchPatch; 153 | sourceTree = ""; 154 | }; 155 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 159 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, 160 | ); 161 | name = "External Frameworks and Libraries"; 162 | sourceTree = ""; 163 | }; 164 | 089C1665FE841158C02AAC07 /* Resources */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 8DC2EF5A0486A6940098B216 /* Info.plist */, 168 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */, 169 | ); 170 | name = Resources; 171 | sourceTree = ""; 172 | }; 173 | 08FB77AEFE84172EC02AAC07 /* Classes */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 3D5BC07E128C44A700B8F5FF /* DiffMatchPatch.h */, 177 | 3D5BC07F128C44A700B8F5FF /* DiffMatchPatch.m */, 178 | 3DC87023129FF4B6001F602B /* NSString+JavaSubstring.h */, 179 | 3DC87024129FF4B6001F602B /* NSString+JavaSubstring.m */, 180 | 3D08D25112A71B9C007A5316 /* NSString+UnicharUtilities.h */, 181 | 3D08D25212A71B9C007A5316 /* NSString+UnicharUtilities.m */, 182 | 3D70BCC6128EDAF80078D1A6 /* NSString+UriCompatibility.h */, 183 | 3D70BCC7128EDAF80078D1A6 /* NSString+UriCompatibility.m */, 184 | 3DEE4C70129D484D00885485 /* NSMutableDictionary+DMPExtensions.h */, 185 | 3DEE4C71129D484D00885485 /* NSMutableDictionary+DMPExtensions.m */, 186 | ); 187 | indentWidth = 2; 188 | name = Classes; 189 | sourceTree = ""; 190 | tabWidth = 2; 191 | usesTabs = 0; 192 | }; 193 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { 194 | isa = PBXGroup; 195 | children = ( 196 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, 197 | ); 198 | name = "Linked Frameworks"; 199 | sourceTree = ""; 200 | }; 201 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */, 205 | ); 206 | name = "Other Frameworks"; 207 | sourceTree = ""; 208 | }; 209 | 32C88DFF0371C24200C91783 /* Other Sources */ = { 210 | isa = PBXGroup; 211 | children = ( 212 | 32DBCF5E0370ADEE00C91783 /* DiffMatchPatch_Prefix.pch */, 213 | 3DA642BC128DEF4900B33CE9 /* MinMaxMacros.h */, 214 | 3DA6416F128DDA3400B33CE9 /* DiffMatchPatchCFUtilities.h */, 215 | 3DA64170128DDA3400B33CE9 /* DiffMatchPatchCFUtilities.c */, 216 | 3DEB56D916DBA4C300D11FA5 /* JXArcCompatibilityMacros.h */, 217 | ); 218 | indentWidth = 2; 219 | name = "Other Sources"; 220 | sourceTree = ""; 221 | tabWidth = 2; 222 | usesTabs = 0; 223 | }; 224 | 3D510E0F12BEBA44008C7CE7 /* Configurations */ = { 225 | isa = PBXGroup; 226 | children = ( 227 | 3D510E1112BEBA44008C7CE7 /* Version.xcconfig */, 228 | 3D510E1012BEBA44008C7CE7 /* Base.xcconfig */, 229 | ); 230 | indentWidth = 2; 231 | path = Configurations; 232 | sourceTree = ""; 233 | tabWidth = 2; 234 | usesTabs = 0; 235 | }; 236 | 3D5BC0D9128CAA7600B8F5FF /* Tests */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | 3D5BC0B0128CA8E200B8F5FF /* DiffMatchPatchTest-Info.plist */, 240 | 3D5BC0DD128CAAE400B8F5FF /* DiffMatchPatchTest.h */, 241 | 3D5BC0DE128CAAE400B8F5FF /* DiffMatchPatchTest.m */, 242 | 3DFF2F3613C2105300DC564A /* TestUtilities.h */, 243 | 3DFF2F3713C2105300DC564A /* TestUtilities.m */, 244 | 3D96F43E12AFC76600C3E5C0 /* speedtest_Prefix.pch */, 245 | 3D96F44912AFC82F00C3E5C0 /* speedtest.m */, 246 | 3D03489A135F75770051FE16 /* mode-test.m */, 247 | ); 248 | indentWidth = 2; 249 | path = Tests; 250 | sourceTree = ""; 251 | tabWidth = 2; 252 | usesTabs = 0; 253 | }; 254 | /* End PBXGroup section */ 255 | 256 | /* Begin PBXHeadersBuildPhase section */ 257 | 8DC2EF500486A6940098B216 /* Headers */ = { 258 | isa = PBXHeadersBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | 3D5BC080128C44A700B8F5FF /* DiffMatchPatch.h in Headers */, 262 | 3DDD039D15F7BBFA00EF6F80 /* DiffMatchPatchCFUtilities.h in Headers */, 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | /* End PBXHeadersBuildPhase section */ 267 | 268 | /* Begin PBXNativeTarget section */ 269 | 3D03488D135F75460051FE16 /* mode-test */ = { 270 | isa = PBXNativeTarget; 271 | buildConfigurationList = 3D034899135F75640051FE16 /* Build configuration list for PBXNativeTarget "mode-test" */; 272 | buildPhases = ( 273 | 3D03488B135F75460051FE16 /* Sources */, 274 | 3D03488C135F75460051FE16 /* Frameworks */, 275 | ); 276 | buildRules = ( 277 | ); 278 | dependencies = ( 279 | 3D0348CD135F7B020051FE16 /* PBXTargetDependency */, 280 | ); 281 | name = "mode-test"; 282 | productName = "mode-test"; 283 | productReference = 3D03488E135F75460051FE16 /* mode-test */; 284 | productType = "com.apple.product-type.tool"; 285 | }; 286 | 3D5BC0AE128CA8E200B8F5FF /* DiffMatchPatchTest */ = { 287 | isa = PBXNativeTarget; 288 | buildConfigurationList = 3D5BC0B3128CA8E500B8F5FF /* Build configuration list for PBXNativeTarget "DiffMatchPatchTest" */; 289 | buildPhases = ( 290 | 3D5BC0AA128CA8E200B8F5FF /* Resources */, 291 | 3D5BC0AB128CA8E200B8F5FF /* Sources */, 292 | 3D5BC0AC128CA8E200B8F5FF /* Frameworks */, 293 | ); 294 | buildRules = ( 295 | ); 296 | dependencies = ( 297 | 3DA6427A128DE8CD00B33CE9 /* PBXTargetDependency */, 298 | ); 299 | name = DiffMatchPatchTest; 300 | productName = DiffMatchPatchTest; 301 | productReference = 3D5BC0AF128CA8E200B8F5FF /* DiffMatchPatchTest.xctest */; 302 | productType = "com.apple.product-type.bundle.unit-test"; 303 | }; 304 | 3D96F3A112AFC68900C3E5C0 /* speedtest */ = { 305 | isa = PBXNativeTarget; 306 | buildConfigurationList = 3D96F3B512AFC68E00C3E5C0 /* Build configuration list for PBXNativeTarget "speedtest" */; 307 | buildPhases = ( 308 | 3D96F39F12AFC68900C3E5C0 /* Sources */, 309 | 3D96F3A012AFC68900C3E5C0 /* Frameworks */, 310 | ); 311 | buildRules = ( 312 | ); 313 | dependencies = ( 314 | 3D96F3B912AFC6CD00C3E5C0 /* PBXTargetDependency */, 315 | ); 316 | name = speedtest; 317 | productName = speedtest; 318 | productReference = 3D96F3A212AFC68900C3E5C0 /* speedtest */; 319 | productType = "com.apple.product-type.tool"; 320 | }; 321 | 8DC2EF4F0486A6940098B216 /* DiffMatchPatch */ = { 322 | isa = PBXNativeTarget; 323 | buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "DiffMatchPatch" */; 324 | buildPhases = ( 325 | 8DC2EF500486A6940098B216 /* Headers */, 326 | 8DC2EF520486A6940098B216 /* Resources */, 327 | 8DC2EF540486A6940098B216 /* Sources */, 328 | 8DC2EF560486A6940098B216 /* Frameworks */, 329 | ); 330 | buildRules = ( 331 | ); 332 | dependencies = ( 333 | ); 334 | name = DiffMatchPatch; 335 | productInstallPath = "$(HOME)/Library/Frameworks"; 336 | productName = DiffMatchPatch; 337 | productReference = 8DC2EF5B0486A6940098B216 /* DiffMatchPatch.framework */; 338 | productType = "com.apple.product-type.framework"; 339 | }; 340 | /* End PBXNativeTarget section */ 341 | 342 | /* Begin PBXProject section */ 343 | 0867D690FE84028FC02AAC07 /* Project object */ = { 344 | isa = PBXProject; 345 | attributes = { 346 | LastUpgradeCheck = 1220; 347 | }; 348 | buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "DiffMatchPatch" */; 349 | compatibilityVersion = "Xcode 3.2"; 350 | developmentRegion = en; 351 | hasScannedForEncodings = 1; 352 | knownRegions = ( 353 | en, 354 | ja, 355 | fr, 356 | de, 357 | Base, 358 | ); 359 | mainGroup = 0867D691FE84028FC02AAC07 /* DiffMatchPatch */; 360 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 361 | projectDirPath = ""; 362 | projectRoot = ""; 363 | targets = ( 364 | 8DC2EF4F0486A6940098B216 /* DiffMatchPatch */, 365 | 3D5BC0AE128CA8E200B8F5FF /* DiffMatchPatchTest */, 366 | 3D96F3A112AFC68900C3E5C0 /* speedtest */, 367 | 3D03488D135F75460051FE16 /* mode-test */, 368 | ); 369 | }; 370 | /* End PBXProject section */ 371 | 372 | /* Begin PBXResourcesBuildPhase section */ 373 | 3D5BC0AA128CA8E200B8F5FF /* Resources */ = { 374 | isa = PBXResourcesBuildPhase; 375 | buildActionMask = 2147483647; 376 | files = ( 377 | ); 378 | runOnlyForDeploymentPostprocessing = 0; 379 | }; 380 | 8DC2EF520486A6940098B216 /* Resources */ = { 381 | isa = PBXResourcesBuildPhase; 382 | buildActionMask = 2147483647; 383 | files = ( 384 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */, 385 | ); 386 | runOnlyForDeploymentPostprocessing = 0; 387 | }; 388 | /* End PBXResourcesBuildPhase section */ 389 | 390 | /* Begin PBXSourcesBuildPhase section */ 391 | 3D03488B135F75460051FE16 /* Sources */ = { 392 | isa = PBXSourcesBuildPhase; 393 | buildActionMask = 2147483647; 394 | files = ( 395 | 3D03489B135F75770051FE16 /* mode-test.m in Sources */, 396 | 3DFF2F3913C2105300DC564A /* TestUtilities.m in Sources */, 397 | ); 398 | runOnlyForDeploymentPostprocessing = 0; 399 | }; 400 | 3D5BC0AB128CA8E200B8F5FF /* Sources */ = { 401 | isa = PBXSourcesBuildPhase; 402 | buildActionMask = 2147483647; 403 | files = ( 404 | 3DA64278128DE8C900B33CE9 /* DiffMatchPatchTest.m in Sources */, 405 | ); 406 | runOnlyForDeploymentPostprocessing = 0; 407 | }; 408 | 3D96F39F12AFC68900C3E5C0 /* Sources */ = { 409 | isa = PBXSourcesBuildPhase; 410 | buildActionMask = 2147483647; 411 | files = ( 412 | 3D96F44A12AFC82F00C3E5C0 /* speedtest.m in Sources */, 413 | 3DFF2F3813C2105300DC564A /* TestUtilities.m in Sources */, 414 | ); 415 | runOnlyForDeploymentPostprocessing = 0; 416 | }; 417 | 8DC2EF540486A6940098B216 /* Sources */ = { 418 | isa = PBXSourcesBuildPhase; 419 | buildActionMask = 2147483647; 420 | files = ( 421 | 3D5BC081128C44A700B8F5FF /* DiffMatchPatch.m in Sources */, 422 | 3DA641D1128DE21D00B33CE9 /* DiffMatchPatchCFUtilities.c in Sources */, 423 | 3D70BCC9128EDAF80078D1A6 /* NSString+UriCompatibility.m in Sources */, 424 | 3DEE4C73129D484D00885485 /* NSMutableDictionary+DMPExtensions.m in Sources */, 425 | 3DC87026129FF4B6001F602B /* NSString+JavaSubstring.m in Sources */, 426 | 3D08D25412A71B9C007A5316 /* NSString+UnicharUtilities.m in Sources */, 427 | ); 428 | runOnlyForDeploymentPostprocessing = 0; 429 | }; 430 | /* End PBXSourcesBuildPhase section */ 431 | 432 | /* Begin PBXTargetDependency section */ 433 | 3D0348CD135F7B020051FE16 /* PBXTargetDependency */ = { 434 | isa = PBXTargetDependency; 435 | target = 8DC2EF4F0486A6940098B216 /* DiffMatchPatch */; 436 | targetProxy = 3D0348CC135F7B020051FE16 /* PBXContainerItemProxy */; 437 | }; 438 | 3D96F3B912AFC6CD00C3E5C0 /* PBXTargetDependency */ = { 439 | isa = PBXTargetDependency; 440 | target = 8DC2EF4F0486A6940098B216 /* DiffMatchPatch */; 441 | targetProxy = 3D96F3B812AFC6CD00C3E5C0 /* PBXContainerItemProxy */; 442 | }; 443 | 3DA6427A128DE8CD00B33CE9 /* PBXTargetDependency */ = { 444 | isa = PBXTargetDependency; 445 | target = 8DC2EF4F0486A6940098B216 /* DiffMatchPatch */; 446 | targetProxy = 3DA64279128DE8CD00B33CE9 /* PBXContainerItemProxy */; 447 | }; 448 | /* End PBXTargetDependency section */ 449 | 450 | /* Begin PBXVariantGroup section */ 451 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { 452 | isa = PBXVariantGroup; 453 | children = ( 454 | D7DC14552572BF0F00CF8E50 /* en */, 455 | ); 456 | name = InfoPlist.strings; 457 | sourceTree = ""; 458 | }; 459 | /* End PBXVariantGroup section */ 460 | 461 | /* Begin XCBuildConfiguration section */ 462 | 1DEB91AE08733DA50010E9CD /* Debug */ = { 463 | isa = XCBuildConfiguration; 464 | buildSettings = { 465 | ALWAYS_SEARCH_USER_PATHS = NO; 466 | CLANG_ENABLE_OBJC_ARC = YES; 467 | CLANG_ENABLE_OBJC_WEAK = YES; 468 | COMBINE_HIDPI_IMAGES = YES; 469 | COPY_PHASE_STRIP = NO; 470 | DYLIB_COMPATIBILITY_VERSION = 1; 471 | DYLIB_CURRENT_VERSION = 1; 472 | FRAMEWORK_VERSION = A; 473 | GCC_DYNAMIC_NO_PIC = NO; 474 | GCC_OPTIMIZATION_LEVEL = 0; 475 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 476 | GCC_PREFIX_HEADER = DiffMatchPatch_Prefix.pch; 477 | INFOPLIST_FILE = Info.plist; 478 | INSTALL_PATH = "@rpath"; 479 | PRODUCT_BUNDLE_IDENTIFIER = "de.geheimwerk.${PRODUCT_NAME}"; 480 | PRODUCT_NAME = DiffMatchPatch; 481 | SKIP_INSTALL = YES; 482 | WRAPPER_EXTENSION = framework; 483 | }; 484 | name = Debug; 485 | }; 486 | 1DEB91AF08733DA50010E9CD /* Release */ = { 487 | isa = XCBuildConfiguration; 488 | buildSettings = { 489 | ALWAYS_SEARCH_USER_PATHS = NO; 490 | CLANG_ENABLE_OBJC_ARC = YES; 491 | CLANG_ENABLE_OBJC_WEAK = YES; 492 | COMBINE_HIDPI_IMAGES = YES; 493 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 494 | DYLIB_COMPATIBILITY_VERSION = 1; 495 | DYLIB_CURRENT_VERSION = 1; 496 | FRAMEWORK_VERSION = A; 497 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 498 | GCC_PREFIX_HEADER = DiffMatchPatch_Prefix.pch; 499 | INFOPLIST_FILE = Info.plist; 500 | INSTALL_PATH = "@rpath"; 501 | PRODUCT_BUNDLE_IDENTIFIER = "de.geheimwerk.${PRODUCT_NAME}"; 502 | PRODUCT_NAME = DiffMatchPatch; 503 | SKIP_INSTALL = YES; 504 | WRAPPER_EXTENSION = framework; 505 | }; 506 | name = Release; 507 | }; 508 | 1DEB91B208733DA50010E9CD /* Debug */ = { 509 | isa = XCBuildConfiguration; 510 | baseConfigurationReference = 3D510E1012BEBA44008C7CE7 /* Base.xcconfig */; 511 | buildSettings = { 512 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 513 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 514 | CLANG_WARN_BOOL_CONVERSION = YES; 515 | CLANG_WARN_COMMA = YES; 516 | CLANG_WARN_CONSTANT_CONVERSION = YES; 517 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 518 | CLANG_WARN_EMPTY_BODY = YES; 519 | CLANG_WARN_ENUM_CONVERSION = YES; 520 | CLANG_WARN_INFINITE_RECURSION = YES; 521 | CLANG_WARN_INT_CONVERSION = YES; 522 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 523 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 524 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 525 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 526 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 527 | CLANG_WARN_STRICT_PROTOTYPES = YES; 528 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 529 | CLANG_WARN_UNREACHABLE_CODE = YES; 530 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 531 | ENABLE_STRICT_OBJC_MSGSEND = YES; 532 | ENABLE_TESTABILITY = YES; 533 | GCC_NO_COMMON_BLOCKS = YES; 534 | GCC_OPTIMIZATION_LEVEL = 0; 535 | GCC_WARN_UNINITIALIZED_AUTOS = NO; 536 | MACOSX_DEPLOYMENT_TARGET = 10.9; 537 | ONLY_ACTIVE_ARCH = YES; 538 | }; 539 | name = Debug; 540 | }; 541 | 1DEB91B308733DA50010E9CD /* Release */ = { 542 | isa = XCBuildConfiguration; 543 | baseConfigurationReference = 3D510E1012BEBA44008C7CE7 /* Base.xcconfig */; 544 | buildSettings = { 545 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 546 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 547 | CLANG_WARN_BOOL_CONVERSION = YES; 548 | CLANG_WARN_COMMA = YES; 549 | CLANG_WARN_CONSTANT_CONVERSION = YES; 550 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 551 | CLANG_WARN_EMPTY_BODY = YES; 552 | CLANG_WARN_ENUM_CONVERSION = YES; 553 | CLANG_WARN_INFINITE_RECURSION = YES; 554 | CLANG_WARN_INT_CONVERSION = YES; 555 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 556 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 557 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 558 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 559 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 560 | CLANG_WARN_STRICT_PROTOTYPES = YES; 561 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 562 | CLANG_WARN_UNREACHABLE_CODE = YES; 563 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 564 | ENABLE_STRICT_OBJC_MSGSEND = YES; 565 | GCC_NO_COMMON_BLOCKS = YES; 566 | MACOSX_DEPLOYMENT_TARGET = 10.9; 567 | }; 568 | name = Release; 569 | }; 570 | 3D034890135F75460051FE16 /* Debug */ = { 571 | isa = XCBuildConfiguration; 572 | buildSettings = { 573 | ALWAYS_SEARCH_USER_PATHS = NO; 574 | CLANG_ENABLE_OBJC_WEAK = YES; 575 | CODE_SIGN_IDENTITY = "-"; 576 | COPY_PHASE_STRIP = NO; 577 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 578 | GCC_DYNAMIC_NO_PIC = NO; 579 | GCC_OPTIMIZATION_LEVEL = 0; 580 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 581 | GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; 582 | INSTALL_PATH = /usr/local/bin; 583 | LD_RUNPATH_SEARCH_PATHS = "@loader_path/"; 584 | OTHER_LDFLAGS = ( 585 | "-framework", 586 | Foundation, 587 | "-framework", 588 | AppKit, 589 | ); 590 | PRODUCT_NAME = "mode-test"; 591 | }; 592 | name = Debug; 593 | }; 594 | 3D034892135F75460051FE16 /* Release */ = { 595 | isa = XCBuildConfiguration; 596 | buildSettings = { 597 | ALWAYS_SEARCH_USER_PATHS = NO; 598 | CLANG_ENABLE_OBJC_WEAK = YES; 599 | CODE_SIGN_IDENTITY = "-"; 600 | COPY_PHASE_STRIP = YES; 601 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 602 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 603 | GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; 604 | INSTALL_PATH = /usr/local/bin; 605 | LD_RUNPATH_SEARCH_PATHS = "@loader_path/"; 606 | OTHER_LDFLAGS = ( 607 | "-framework", 608 | Foundation, 609 | "-framework", 610 | AppKit, 611 | ); 612 | PRODUCT_NAME = "mode-test"; 613 | }; 614 | name = Release; 615 | }; 616 | 3D5BC0B1128CA8E500B8F5FF /* Debug */ = { 617 | isa = XCBuildConfiguration; 618 | buildSettings = { 619 | ALWAYS_SEARCH_USER_PATHS = NO; 620 | CLANG_ENABLE_OBJC_WEAK = YES; 621 | COMBINE_HIDPI_IMAGES = YES; 622 | COPY_PHASE_STRIP = NO; 623 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 624 | GCC_DYNAMIC_NO_PIC = NO; 625 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 626 | GCC_OPTIMIZATION_LEVEL = 0; 627 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 628 | GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Cocoa.framework/Headers/Cocoa.h"; 629 | INFOPLIST_FILE = "Tests/DiffMatchPatchTest-Info.plist"; 630 | INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles"; 631 | OTHER_LDFLAGS = ( 632 | "-framework", 633 | Cocoa, 634 | ); 635 | PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.${PRODUCT_NAME}"; 636 | PRODUCT_NAME = DiffMatchPatchTest; 637 | }; 638 | name = Debug; 639 | }; 640 | 3D5BC0B2128CA8E500B8F5FF /* Release */ = { 641 | isa = XCBuildConfiguration; 642 | buildSettings = { 643 | ALWAYS_SEARCH_USER_PATHS = NO; 644 | CLANG_ENABLE_OBJC_WEAK = YES; 645 | COMBINE_HIDPI_IMAGES = YES; 646 | COPY_PHASE_STRIP = YES; 647 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 648 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 649 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 650 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 651 | GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Cocoa.framework/Headers/Cocoa.h"; 652 | INFOPLIST_FILE = "Tests/DiffMatchPatchTest-Info.plist"; 653 | INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles"; 654 | OTHER_LDFLAGS = ( 655 | "-framework", 656 | Cocoa, 657 | ); 658 | PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.${PRODUCT_NAME}"; 659 | PRODUCT_NAME = DiffMatchPatchTest; 660 | }; 661 | name = Release; 662 | }; 663 | 3D96F3A412AFC68B00C3E5C0 /* Debug */ = { 664 | isa = XCBuildConfiguration; 665 | buildSettings = { 666 | ALWAYS_SEARCH_USER_PATHS = NO; 667 | CLANG_ENABLE_OBJC_WEAK = YES; 668 | CODE_SIGN_IDENTITY = "-"; 669 | COPY_PHASE_STRIP = NO; 670 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 671 | GCC_DYNAMIC_NO_PIC = NO; 672 | GCC_OPTIMIZATION_LEVEL = 0; 673 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 674 | GCC_PREFIX_HEADER = speedtest_Prefix.pch; 675 | INSTALL_PATH = /usr/local/bin; 676 | LD_RUNPATH_SEARCH_PATHS = "@loader_path/"; 677 | OTHER_LDFLAGS = ( 678 | "-framework", 679 | Foundation, 680 | "-framework", 681 | AppKit, 682 | ); 683 | PRODUCT_NAME = speedtest; 684 | }; 685 | name = Debug; 686 | }; 687 | 3D96F3A512AFC68B00C3E5C0 /* Release */ = { 688 | isa = XCBuildConfiguration; 689 | buildSettings = { 690 | ALWAYS_SEARCH_USER_PATHS = NO; 691 | CLANG_ENABLE_OBJC_WEAK = YES; 692 | CODE_SIGN_IDENTITY = "-"; 693 | COPY_PHASE_STRIP = YES; 694 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 695 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 696 | GCC_PREFIX_HEADER = speedtest_Prefix.pch; 697 | INSTALL_PATH = /usr/local/bin; 698 | LD_RUNPATH_SEARCH_PATHS = "@loader_path/"; 699 | OTHER_LDFLAGS = ( 700 | "-framework", 701 | Foundation, 702 | "-framework", 703 | AppKit, 704 | ); 705 | PRODUCT_NAME = speedtest; 706 | }; 707 | name = Release; 708 | }; 709 | /* End XCBuildConfiguration section */ 710 | 711 | /* Begin XCConfigurationList section */ 712 | 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "DiffMatchPatch" */ = { 713 | isa = XCConfigurationList; 714 | buildConfigurations = ( 715 | 1DEB91AE08733DA50010E9CD /* Debug */, 716 | 1DEB91AF08733DA50010E9CD /* Release */, 717 | ); 718 | defaultConfigurationIsVisible = 0; 719 | defaultConfigurationName = Debug; 720 | }; 721 | 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "DiffMatchPatch" */ = { 722 | isa = XCConfigurationList; 723 | buildConfigurations = ( 724 | 1DEB91B208733DA50010E9CD /* Debug */, 725 | 1DEB91B308733DA50010E9CD /* Release */, 726 | ); 727 | defaultConfigurationIsVisible = 0; 728 | defaultConfigurationName = Debug; 729 | }; 730 | 3D034899135F75640051FE16 /* Build configuration list for PBXNativeTarget "mode-test" */ = { 731 | isa = XCConfigurationList; 732 | buildConfigurations = ( 733 | 3D034890135F75460051FE16 /* Debug */, 734 | 3D034892135F75460051FE16 /* Release */, 735 | ); 736 | defaultConfigurationIsVisible = 0; 737 | defaultConfigurationName = Debug; 738 | }; 739 | 3D5BC0B3128CA8E500B8F5FF /* Build configuration list for PBXNativeTarget "DiffMatchPatchTest" */ = { 740 | isa = XCConfigurationList; 741 | buildConfigurations = ( 742 | 3D5BC0B1128CA8E500B8F5FF /* Debug */, 743 | 3D5BC0B2128CA8E500B8F5FF /* Release */, 744 | ); 745 | defaultConfigurationIsVisible = 0; 746 | defaultConfigurationName = Debug; 747 | }; 748 | 3D96F3B512AFC68E00C3E5C0 /* Build configuration list for PBXNativeTarget "speedtest" */ = { 749 | isa = XCConfigurationList; 750 | buildConfigurations = ( 751 | 3D96F3A412AFC68B00C3E5C0 /* Debug */, 752 | 3D96F3A512AFC68B00C3E5C0 /* Release */, 753 | ); 754 | defaultConfigurationIsVisible = 0; 755 | defaultConfigurationName = Debug; 756 | }; 757 | /* End XCConfigurationList section */ 758 | }; 759 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 760 | } 761 | -------------------------------------------------------------------------------- /DiffMatchPatchCFUtilities.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #include 24 | 25 | #include "DiffMatchPatchCFUtilities.h" 26 | 27 | #include "MinMaxMacros.h" 28 | #include 29 | #include 30 | #include 31 | 32 | Boolean diff_regExMatch(CFStringRef text, const regex_t *re); 33 | 34 | CFArrayRef diff_halfMatchICreate(CFStringRef longtext, CFStringRef shorttext, CFIndex i); 35 | 36 | void diff_mungeHelper(CFStringRef token, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash, CFMutableStringRef chars); 37 | 38 | // Utility functions 39 | CFStringRef diff_CFStringCreateFromUnichar(UniChar ch) { 40 | CFStringRef c = CFStringCreateWithCharacters(kCFAllocatorDefault, &ch, 1); 41 | return c; 42 | } 43 | 44 | Boolean diff_regExMatch(CFStringRef text, const regex_t *re) { 45 | //TODO(jan): Using regex.h is far from optimal. Find an alternative. 46 | Boolean isMatch; 47 | const char *bytes; 48 | char *localBuffer = NULL; 49 | char *textCString = NULL; 50 | // We are only interested in line endings anyway so ASCII is fine. 51 | CFStringEncoding encoding = kCFStringEncodingASCII; 52 | 53 | bytes = CFStringGetCStringPtr(text, encoding); 54 | 55 | if (bytes == NULL) { 56 | Boolean success; 57 | CFIndex length; 58 | CFIndex usedBufferLength; 59 | CFIndex textLength = CFStringGetLength(text); 60 | CFRange rangeToProcess = CFRangeMake(0, textLength); 61 | 62 | success = (CFStringGetBytes(text, rangeToProcess, encoding, '?', false, NULL, LONG_MAX, &usedBufferLength) > 0); 63 | if (success) { 64 | length = usedBufferLength + 1; 65 | 66 | localBuffer = calloc(length, sizeof(char)); 67 | success = (CFStringGetBytes(text, rangeToProcess, encoding, '?', false, (UInt8 *)localBuffer, length, NULL) > 0); 68 | 69 | if (success) { 70 | textCString = localBuffer; 71 | } 72 | } 73 | } else { 74 | textCString = (char *)bytes; 75 | } 76 | 77 | if (textCString != NULL) { 78 | isMatch = (regexec(re, textCString, 0, NULL, 0) == 0); 79 | } else { 80 | isMatch = false; 81 | //check(0); 82 | } 83 | 84 | if (localBuffer != NULL) { 85 | free(localBuffer); 86 | } 87 | 88 | return isMatch; 89 | } 90 | 91 | 92 | /** 93 | * Determine the common prefix of two strings. 94 | * @param text1 First string. 95 | * @param text2 Second string. 96 | * @return The number of characters common to the start of each string. 97 | */ 98 | CFIndex diff_commonPrefix(CFStringRef text1, CFStringRef text2) { 99 | // Performance analysis: http://neil.fraser.name/news/2007/10/09/ 100 | CFIndex text1_length = CFStringGetLength(text1); 101 | CFIndex text2_length = CFStringGetLength(text2); 102 | 103 | CFStringInlineBuffer text1_inlineBuffer, text2_inlineBuffer; 104 | CFStringInitInlineBuffer(text1, &text1_inlineBuffer, CFRangeMake(0, text1_length)); 105 | CFStringInitInlineBuffer(text2, &text2_inlineBuffer, CFRangeMake(0, text2_length)); 106 | 107 | UniChar char1, char2; 108 | CFIndex n = MIN(text1_length, text2_length); 109 | 110 | for (CFIndex i = 0; i < n; i++) { 111 | char1 = CFStringGetCharacterFromInlineBuffer(&text1_inlineBuffer, i); 112 | char2 = CFStringGetCharacterFromInlineBuffer(&text2_inlineBuffer, i); 113 | 114 | if (char1 != char2) { 115 | return i; 116 | } 117 | } 118 | 119 | return n; 120 | } 121 | 122 | /** 123 | * Determine the common suffix of two strings. 124 | * @param text1 First string. 125 | * @param text2 Second string. 126 | * @return The number of characters common to the end of each string. 127 | */ 128 | CFIndex diff_commonSuffix(CFStringRef text1, CFStringRef text2) { 129 | // Performance analysis: http://neil.fraser.name/news/2007/10/09/ 130 | CFIndex text1_length = CFStringGetLength(text1); 131 | CFIndex text2_length = CFStringGetLength(text2); 132 | 133 | CFStringInlineBuffer text1_inlineBuffer, text2_inlineBuffer; 134 | CFStringInitInlineBuffer(text1, &text1_inlineBuffer, CFRangeMake(0, text1_length)); 135 | CFStringInitInlineBuffer(text2, &text2_inlineBuffer, CFRangeMake(0, text2_length)); 136 | 137 | UniChar char1, char2; 138 | CFIndex n = MIN(text1_length, text2_length); 139 | 140 | for (CFIndex i = 1; i <= n; i++) { 141 | char1 = CFStringGetCharacterFromInlineBuffer(&text1_inlineBuffer, (text1_length - i)); 142 | char2 = CFStringGetCharacterFromInlineBuffer(&text2_inlineBuffer, (text2_length - i)); 143 | 144 | if (char1 != char2) { 145 | return i - 1; 146 | } 147 | } 148 | return n; 149 | } 150 | 151 | /** 152 | * Determine if the suffix of one CFStringRef is the prefix of another. 153 | * @param text1 First CFStringRef. 154 | * @param text2 Second CFStringRef. 155 | * @return The number of characters common to the end of the first 156 | * CFStringRef and the start of the second CFStringRef. 157 | */ 158 | CFIndex diff_commonOverlap(CFStringRef text1, CFStringRef text2) { 159 | CFIndex common_overlap = 0; 160 | 161 | // Cache the text lengths to prevent multiple calls. 162 | CFIndex text1_length = CFStringGetLength(text1); 163 | CFIndex text2_length = CFStringGetLength(text2); 164 | 165 | // Eliminate the nil case. 166 | if (text1_length == 0 || text2_length == 0) { 167 | return 0; 168 | } 169 | 170 | // Truncate the longer CFStringRef. 171 | CFStringRef text1_trunc; 172 | CFStringRef text2_trunc; 173 | CFIndex text1_trunc_length; 174 | if (text1_length > text2_length) { 175 | text1_trunc_length = text2_length; 176 | text1_trunc = diff_CFStringCreateRightSubstring(text1, text1_length, text1_trunc_length); 177 | 178 | text2_trunc = CFRetain(text2); 179 | } else if (text1_length < text2_length) { 180 | text1_trunc_length = text1_length; 181 | text1_trunc = CFRetain(text1); 182 | 183 | CFIndex text2_trunc_length = text1_length; 184 | text2_trunc = diff_CFStringCreateLeftSubstring(text2, text2_trunc_length); 185 | } else { 186 | text1_trunc_length = text1_length; 187 | text1_trunc = CFRetain(text1); 188 | 189 | text2_trunc = CFRetain(text2); 190 | } 191 | 192 | CFIndex text_length = MIN(text1_length, text2_length); 193 | // Quick check for the worst case. 194 | if (CFStringCompare(text1_trunc, text2_trunc, 0) == kCFCompareEqualTo) { 195 | common_overlap = text_length; 196 | } else { 197 | // Start by looking for a single character match 198 | // and increase length until no match is found. 199 | // Performance analysis: http://neil.fraser.name/news/2010/11/04/ 200 | CFIndex best = 0; 201 | CFIndex length = 1; 202 | while (true) { 203 | CFStringRef pattern = diff_CFStringCreateRightSubstring(text1_trunc, text1_trunc_length, length); 204 | CFRange foundRange = CFStringFind(text2_trunc, pattern, 0); 205 | CFRelease(pattern); 206 | 207 | CFIndex found = foundRange.location; 208 | if (found == kCFNotFound) { 209 | common_overlap = best; 210 | break; 211 | } 212 | length += found; 213 | 214 | CFStringRef text1_sub = diff_CFStringCreateRightSubstring(text1_trunc, text1_trunc_length, length); 215 | CFStringRef text2_sub = diff_CFStringCreateLeftSubstring(text2_trunc, length); 216 | 217 | if (found == 0 || (CFStringCompare(text1_sub, text2_sub, 0) == kCFCompareEqualTo)) { 218 | best = length; 219 | length++; 220 | } 221 | 222 | CFRelease(text1_sub); 223 | CFRelease(text2_sub); 224 | } 225 | } 226 | 227 | CFRelease(text1_trunc); 228 | CFRelease(text2_trunc); 229 | return common_overlap; 230 | } 231 | 232 | /** 233 | * Do the two texts share a Substring which is at least half the length of 234 | * the longer text? 235 | * This speedup can produce non-minimal diffs. 236 | * @param text1 First CFStringRef. 237 | * @param text2 Second CFStringRef. 238 | * @param diffTimeout Time limit for diff. 239 | * @return Five element CFStringRef array, containing the prefix of text1, the 240 | * suffix of text1, the prefix of text2, the suffix of text2 and the 241 | * common middle. Or NULL if there was no match. 242 | */ 243 | CFArrayRef diff_halfMatchCreate(CFStringRef text1, CFStringRef text2, const float diffTimeout) { 244 | if (diffTimeout <= 0) { 245 | // Don't risk returning a non-optimal diff if we have unlimited time. 246 | return NULL; 247 | } 248 | CFStringRef longtext = CFStringGetLength(text1) > CFStringGetLength(text2) ? text1 : text2; 249 | CFStringRef shorttext = CFStringGetLength(text1) > CFStringGetLength(text2) ? text2 : text1; 250 | if (CFStringGetLength(longtext) < 4 || CFStringGetLength(shorttext) * 2 < CFStringGetLength(longtext)) { 251 | return NULL; // Pointless. 252 | } 253 | 254 | // First check if the second quarter is the seed for a half-match. 255 | CFArrayRef hm1 = diff_halfMatchICreate(longtext, shorttext, 256 | (CFStringGetLength(longtext) + 3) / 4); 257 | // Check again based on the third quarter. 258 | CFArrayRef hm2 = diff_halfMatchICreate(longtext, shorttext, 259 | (CFStringGetLength(longtext) + 1) / 2); 260 | CFArrayRef hm; 261 | if (hm1 == NULL && hm2 == NULL) { 262 | return NULL; 263 | } else if (hm2 == NULL) { 264 | hm = CFRetain(hm1); 265 | } else if (hm1 == NULL) { 266 | hm = CFRetain(hm2); 267 | } else { 268 | // Both matched. Select the longest. 269 | hm = CFStringGetLength(CFArrayGetValueAtIndex(hm1, 4)) > CFStringGetLength(CFArrayGetValueAtIndex(hm2, 4)) ? CFRetain(hm1) : CFRetain(hm2); 270 | } 271 | 272 | if (hm1 != NULL) { 273 | CFRelease(hm1); 274 | } 275 | if (hm2 != NULL) { 276 | CFRelease(hm2); 277 | } 278 | 279 | // A half-match was found, sort out the return data. 280 | if (CFStringGetLength(text1) > CFStringGetLength(text2)) { 281 | return hm; 282 | //return new CFStringRef[]{hm[0], hm[1], hm[2], hm[3], hm[4]}; 283 | } else { 284 | // { hm[0], hm[1], hm[2], hm[3], hm[4] } 285 | // => { hm[2], hm[3], hm[0], hm[1], hm[4] } 286 | 287 | CFMutableArrayRef hm_mutable = CFArrayCreateMutableCopy(kCFAllocatorDefault, CFArrayGetCount(hm), hm); 288 | 289 | CFRelease(hm); 290 | 291 | CFArrayExchangeValuesAtIndices(hm_mutable, 0, 2); 292 | CFArrayExchangeValuesAtIndices(hm_mutable, 1, 3); 293 | return hm_mutable; 294 | } 295 | } 296 | 297 | /** 298 | * Does a Substring of shorttext exist within longtext such that the 299 | * Substring is at least half the length of longtext? 300 | * @param longtext Longer CFStringRef. 301 | * @param shorttext Shorter CFStringRef. 302 | * @param i Start index of quarter length Substring within longtext. 303 | * @return Five element CFStringRef array, containing the prefix of longtext, the 304 | * suffix of longtext, the prefix of shorttext, the suffix of shorttext 305 | * and the common middle. Or NULL if there was no match. 306 | */ 307 | CFArrayRef diff_halfMatchICreate(CFStringRef longtext, CFStringRef shorttext, CFIndex i) { 308 | // Start with a 1/4 length Substring at position i as a seed. 309 | CFStringRef seed = diff_CFStringCreateSubstring(longtext, i, CFStringGetLength(longtext) / 4); 310 | CFIndex j = -1; 311 | CFStringRef best_common = CFSTR(""); 312 | CFStringRef best_longtext_a = CFSTR(""), best_longtext_b = CFSTR(""); 313 | CFStringRef best_shorttext_a = CFSTR(""), best_shorttext_b = CFSTR(""); 314 | 315 | CFStringRef longtext_substring, shorttext_substring; 316 | CFIndex shorttext_length = CFStringGetLength(shorttext); 317 | CFRange resultRange; 318 | CFRange rangeToSearch; 319 | rangeToSearch.length = shorttext_length - (j + 1); 320 | rangeToSearch.location = j + 1; 321 | 322 | while (j < CFStringGetLength(shorttext) 323 | && (CFStringFindWithOptions(shorttext, seed, rangeToSearch, 0, &resultRange) == true)) { 324 | j = resultRange.location; 325 | rangeToSearch.length = shorttext_length - (j + 1); 326 | rangeToSearch.location = j + 1; 327 | 328 | longtext_substring = diff_CFStringCreateSubstringWithStartIndex(longtext, i); 329 | shorttext_substring = diff_CFStringCreateSubstringWithStartIndex(shorttext, j); 330 | 331 | CFIndex prefixLength = diff_commonPrefix(longtext_substring, shorttext_substring); 332 | 333 | CFRelease(longtext_substring); 334 | CFRelease(shorttext_substring); 335 | 336 | longtext_substring = diff_CFStringCreateLeftSubstring(longtext, i); 337 | shorttext_substring = diff_CFStringCreateLeftSubstring(shorttext, j); 338 | 339 | CFIndex suffixLength = diff_commonSuffix(longtext_substring, shorttext_substring); 340 | 341 | CFRelease(longtext_substring); 342 | CFRelease(shorttext_substring); 343 | 344 | if (CFStringGetLength(best_common) < suffixLength + prefixLength) { 345 | CFRelease(best_common); 346 | CFRelease(best_longtext_a); 347 | CFRelease(best_longtext_b); 348 | CFRelease(best_shorttext_a); 349 | CFRelease(best_shorttext_b); 350 | 351 | best_common = diff_CFStringCreateSubstring(shorttext, j - suffixLength, suffixLength + prefixLength); 352 | 353 | best_longtext_a = diff_CFStringCreateLeftSubstring(longtext, i - suffixLength); 354 | best_longtext_b = diff_CFStringCreateSubstringWithStartIndex(longtext, i + prefixLength); 355 | best_shorttext_a = diff_CFStringCreateLeftSubstring(shorttext, j - suffixLength); 356 | best_shorttext_b = diff_CFStringCreateSubstringWithStartIndex(shorttext, j + prefixLength); 357 | } 358 | } 359 | 360 | CFRelease(seed); 361 | 362 | CFArrayRef halfMatchIArray; 363 | if (CFStringGetLength(best_common) * 2 >= CFStringGetLength(longtext)) { 364 | const CFStringRef values[] = { best_longtext_a, best_longtext_b, 365 | best_shorttext_a, best_shorttext_b, best_common }; 366 | halfMatchIArray = CFArrayCreate(kCFAllocatorDefault, (const void **)values, (sizeof(values) / sizeof(values[0])), &kCFTypeArrayCallBacks); 367 | } else { 368 | halfMatchIArray = NULL; 369 | } 370 | 371 | CFRelease(best_common); 372 | CFRelease(best_longtext_a); 373 | CFRelease(best_longtext_b); 374 | CFRelease(best_shorttext_a); 375 | CFRelease(best_shorttext_b); 376 | 377 | return halfMatchIArray; 378 | } 379 | 380 | void diff_mungeHelper(CFStringRef token, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash, CFMutableStringRef chars) { 381 | #define diff_UniCharMax (~(UniChar)0x00) 382 | 383 | CFIndex hash; 384 | 385 | if (CFDictionaryGetValueIfPresent(tokenHash, token, (const void **)&hash)) { 386 | const UniChar hashChar = (UniChar)hash; 387 | CFStringAppendCharacters(chars, &hashChar, 1); 388 | } else { 389 | CFArrayAppendValue(tokenArray, token); 390 | hash = CFArrayGetCount(tokenArray) - 1; 391 | __Check_String(hash <= diff_UniCharMax, "Hash value has exceeded UniCharMax!"); 392 | CFDictionaryAddValue(tokenHash, token, (void *)hash); 393 | const UniChar hashChar = (UniChar)hash; 394 | CFStringAppendCharacters(chars, &hashChar, 1); 395 | } 396 | 397 | #undef diff_UniCharMax 398 | } 399 | 400 | CF_INLINE void diff_mungeTokenForRange(CFStringRef text, CFRange tokenRange, CFMutableStringRef chars, CFMutableDictionaryRef tokenHash, CFMutableArrayRef tokenArray) { 401 | CFStringRef token = CFStringCreateWithSubstring(kCFAllocatorDefault, text, tokenRange); 402 | diff_mungeHelper(token, tokenArray, tokenHash, chars); 403 | CFRelease(token); 404 | } 405 | 406 | /** 407 | * Split a text into a list of strings. Reduce the texts to a CFStringRef of 408 | * hashes where each Unicode character represents one line. 409 | * @param text CFString to encode. 410 | * @param lineArray CFMutableArray of unique strings. 411 | * @param lineHash Map of strings to indices. 412 | * @return Encoded CFStringRef. 413 | */ 414 | CFStringRef diff_linesToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef lineArray, CFMutableDictionaryRef lineHash) { 415 | #define lineStart lineStartRange.location 416 | #define lineEnd lineEndRange.location 417 | 418 | CFRange lineStartRange; 419 | CFRange lineEndRange; 420 | lineStart = 0; 421 | lineEnd = -1; 422 | CFStringRef line; 423 | CFMutableStringRef chars = CFStringCreateMutable(kCFAllocatorDefault, 0); 424 | 425 | CFIndex textLength = CFStringGetLength(text); 426 | 427 | // Walk the text, pulling out a Substring for each line. 428 | // CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, text, CFSTR("\n")) would temporarily double our memory footprint. 429 | // Modifying text would create many large strings. 430 | while (lineEnd < textLength - 1) { 431 | lineStartRange.length = textLength - lineStart; 432 | 433 | if (CFStringFindWithOptions(text, CFSTR("\n"), lineStartRange, 0, &lineEndRange) == false) { 434 | lineEnd = textLength - 1; 435 | } /* else { 436 | lineEnd = lineEndRange.location; 437 | }*/ 438 | 439 | line = diff_CFStringCreateJavaSubstring(text, lineStart, lineEnd + 1); 440 | lineStart = lineEnd + 1; 441 | 442 | diff_mungeHelper(line, lineArray, lineHash, chars); 443 | 444 | CFRelease(line); 445 | } 446 | 447 | return chars; 448 | 449 | #undef diff_UniCharMax 450 | #undef lineStart 451 | #undef lineEnd 452 | } 453 | 454 | /** 455 | * Split a text into a list of strings. Reduce the texts to a CFStringRef of 456 | * hashes where where each Unicode character represents one token (or boundary between tokens). 457 | * @param text CFString to encode. 458 | * @param tokenArray CFMutableArray of unique strings. 459 | * @param tokenHash Map of strings to indices. 460 | * @return Encoded CFStringRef. 461 | */ 462 | CFStringRef diff_tokensToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash, CFOptionFlags tokenizerOptions) { 463 | 464 | CFMutableStringRef chars = CFStringCreateMutable(kCFAllocatorDefault, 0); 465 | 466 | CFIndex textLength = CFStringGetLength(text); 467 | 468 | //CFLocaleRef currentLocale = CFLocaleCopyCurrent(); 469 | 470 | CFRange tokenizerRange = CFRangeMake(0, textLength); 471 | 472 | CFStringTokenizerRef tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, text, tokenizerRange, tokenizerOptions, NULL); 473 | 474 | //CFRelease(currentLocale); 475 | 476 | // Set tokenizer to the start of the string. 477 | CFStringTokenizerTokenType tokenType = CFStringTokenizerGoToTokenAtIndex(tokenizer, 0); 478 | 479 | // Walk the text, pulling out a substring for each token (or boundary between tokens). 480 | // A token is either a word, sentence, paragraph or line depending on what tokenizerOptions is set to. 481 | CFRange tokenRange; 482 | CFIndex prevTokenRangeMax = 0; 483 | while (tokenType != kCFStringTokenizerTokenNone) { 484 | tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer); 485 | 486 | if (tokenRange.location > prevTokenRangeMax) { 487 | // This probably is a bug in the tokenizer: for some reason, gaps in the tokenization can appear. 488 | // One particular example is the tokenizer skipping a line feed ('\n') directly after a string of Chinese characters 489 | CFRange gapRange = CFRangeMake(prevTokenRangeMax, (tokenRange.location - prevTokenRangeMax)); 490 | diff_mungeTokenForRange(text, gapRange, chars, tokenHash, tokenArray); 491 | } 492 | 493 | diff_mungeTokenForRange(text, tokenRange, chars, tokenHash, tokenArray); 494 | 495 | tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer); 496 | 497 | prevTokenRangeMax = (tokenRange.location + tokenRange.length); 498 | } 499 | 500 | CFRelease(tokenizer); 501 | 502 | return chars; 503 | 504 | } 505 | 506 | /** 507 | * Split a text into a list of strings. Reduce the texts to a CFStringRef of 508 | * hashes where where each Unicode character represents the substring for a CFRange. 509 | * @param text CFString to encode. 510 | * @param substringArray CFMutableArray of unique strings. 511 | * @param substringHash Map of strings to indices. 512 | * @param ranges C array of CFRange structs determining the subranges to hash. 513 | * @param ranges_count Count of the CFRange structs contained in ranges. 514 | * @return Encoded CFStringRef. 515 | */ 516 | CFStringRef diff_rangesToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef substringArray, CFMutableDictionaryRef substringHash, CFRange *ranges, size_t ranges_count) { 517 | 518 | CFMutableStringRef chars = CFStringCreateMutable(kCFAllocatorDefault, 0); 519 | 520 | for (size_t i = 0; i < ranges_count; i++) { 521 | CFRange substringRange = ranges[i]; 522 | 523 | diff_mungeTokenForRange(text, substringRange, chars, substringHash, substringArray); 524 | } 525 | 526 | return chars; 527 | 528 | } 529 | 530 | /** 531 | * Split a text into a list of strings. Reduce the texts to a CFStringRef of 532 | * hashes where where each Unicode character represents one word (or boundary between words). 533 | * @param text CFString to encode. 534 | * @param lineArray CFMutableArray of unique strings. 535 | * @param lineHash Map of strings to indices. 536 | * @return Encoded CFStringRef. 537 | */ 538 | CFStringRef diff_wordsToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash) { 539 | 540 | return diff_tokensToCharsMungeCFStringCreate(text, tokenArray, tokenHash, kCFStringTokenizerUnitWordBoundary); 541 | 542 | } 543 | 544 | /** 545 | * Split a text into a list of strings. Reduce the texts to a CFStringRef of 546 | * hashes where where each Unicode character represents one sentence. 547 | * @param text CFString to encode. 548 | * @param lineArray CFMutableArray of unique strings. 549 | * @param lineHash Map of strings to indices. 550 | * @return Encoded CFStringRef. 551 | */ 552 | CFStringRef diff_sentencesToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash) { 553 | 554 | return diff_tokensToCharsMungeCFStringCreate(text, tokenArray, tokenHash, kCFStringTokenizerUnitSentence); 555 | 556 | } 557 | 558 | /** 559 | * Split a text into a list of strings. Reduce the texts to a CFStringRef of 560 | * hashes where where each Unicode character represents one paragraph. 561 | * @param text CFString to encode. 562 | * @param lineArray CFMutableArray of unique strings. 563 | * @param lineHash Map of strings to indices. 564 | * @return Encoded CFStringRef. 565 | */ 566 | CFStringRef diff_paragraphsToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash) { 567 | 568 | return diff_tokensToCharsMungeCFStringCreate(text, tokenArray, tokenHash, kCFStringTokenizerUnitParagraph); 569 | 570 | } 571 | 572 | /** 573 | * Split a text into a list of strings. Reduce the texts to a CFStringRef of 574 | * hashes where each Unicode character represents one text fragment delimitered by line breaks (including the trailing line break characters if any). 575 | * In this context “line break” does not refere to “something you get when you press the return-key”. 576 | * Instead it the refers to “line break boundaries” as defined in “UAX #14: Unicode Line Breaking Algorithm” (http://www.unicode.org/reports/tr14/). 577 | * @param text CFString to encode. 578 | * @param lineArray CFMutableArray of unique strings. 579 | * @param lineHash Map of strings to indices. 580 | * @return Encoded CFStringRef. 581 | */ 582 | CFStringRef diff_lineBreakDelimiteredToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash) { 583 | 584 | return diff_tokensToCharsMungeCFStringCreate(text, tokenArray, tokenHash, kCFStringTokenizerUnitLineBreak); 585 | 586 | } 587 | 588 | CFStringRef diff_charsToTokenCFStringCreate(CFStringRef charsString, CFArrayRef tokenArray) { 589 | #define hashAtIndex(A) hash_chars[(A)] 590 | CFMutableStringRef text = CFStringCreateMutable(kCFAllocatorDefault, 0); 591 | 592 | CFIndex hash_count = CFStringGetLength(charsString); 593 | 594 | const UniChar *hash_chars; 595 | UniChar *hash_buffer = NULL; 596 | diff_CFStringPrepareUniCharBuffer(charsString, &hash_chars, &hash_buffer, CFRangeMake(0, hash_count)); 597 | 598 | for (CFIndex i = 0; i < hash_count; i++) { 599 | CFIndex tokenHash = (CFIndex)hashAtIndex(i); 600 | CFStringRef token = CFArrayGetValueAtIndex(tokenArray, tokenHash); 601 | CFStringAppend(text, token); 602 | } 603 | 604 | if (hash_buffer != NULL) free(hash_buffer); 605 | 606 | return text; 607 | #undef hashAtIndex 608 | } 609 | 610 | /** 611 | * Given two strings, compute a score representing whether the internal 612 | * boundary falls on logical boundaries. 613 | * Scores range from 6 (best) to 0 (worst). 614 | * @param one First CFStringRef. 615 | * @param two Second CFStringRef. 616 | * @return The score. 617 | */ 618 | CFIndex diff_cleanupSemanticScore(CFStringRef one, CFStringRef two) { 619 | static Boolean firstRun = true; 620 | static CFCharacterSetRef alphaNumericSet = NULL; 621 | static CFCharacterSetRef whiteSpaceSet = NULL; 622 | static CFCharacterSetRef controlSet = NULL; 623 | static regex_t blankLineEndRegEx; 624 | static regex_t blankLineStartRegEx; 625 | 626 | if (firstRun) { 627 | alphaNumericSet = CFCharacterSetGetPredefined(kCFCharacterSetAlphaNumeric); 628 | whiteSpaceSet = CFCharacterSetGetPredefined(kCFCharacterSetWhitespaceAndNewline); 629 | controlSet = CFCharacterSetGetPredefined(kCFCharacterSetControl); 630 | 631 | // Define some regex patterns for matching boundaries. 632 | #ifdef DEBUG_CLEANUP_SEMANTIC_SCORE 633 | int status; 634 | status = 635 | #endif 636 | regcomp(&blankLineEndRegEx, "\n\r?\n$", REG_EXTENDED | REG_NOSUB); 637 | #ifdef DEBUG_CLEANUP_SEMANTIC_SCORE 638 | check(status == 0); 639 | status = 640 | #endif 641 | regcomp(&blankLineStartRegEx, "^\r?\n\r?\n", REG_EXTENDED | REG_NOSUB); 642 | #ifdef DEBUG_CLEANUP_SEMANTIC_SCORE 643 | check(status == 0); 644 | #endif 645 | 646 | firstRun = false; 647 | } 648 | 649 | if (CFStringGetLength(one) == 0 || CFStringGetLength(two) == 0) { 650 | // Edges are the best. 651 | return 6; 652 | } 653 | 654 | // Each port of this function behaves slightly differently due to 655 | // subtle differences in each language's definition of things like 656 | // 'whitespace'. Since this function's purpose is largely cosmetic, 657 | // the choice has been made to use each language's native features 658 | // rather than force total conformity. 659 | UniChar char1 = 660 | CFStringGetCharacterAtIndex(one, (CFStringGetLength(one) - 1)); 661 | UniChar char2 = 662 | CFStringGetCharacterAtIndex(two, 0); 663 | Boolean nonAlphaNumeric1 = 664 | !CFCharacterSetIsCharacterMember(alphaNumericSet, char1); 665 | Boolean nonAlphaNumeric2 = 666 | !CFCharacterSetIsCharacterMember(alphaNumericSet, char2); 667 | Boolean whitespace1 = 668 | nonAlphaNumeric1 && CFCharacterSetIsCharacterMember(whiteSpaceSet, char1); 669 | Boolean whitespace2 = 670 | nonAlphaNumeric2 && CFCharacterSetIsCharacterMember(whiteSpaceSet, char2); 671 | Boolean lineBreak1 = 672 | whitespace1 && CFCharacterSetIsCharacterMember(controlSet, char1); 673 | Boolean lineBreak2 = 674 | whitespace2 && CFCharacterSetIsCharacterMember(controlSet, char2); 675 | Boolean blankLine1 = 676 | lineBreak1 && diff_regExMatch(one, &blankLineEndRegEx); 677 | Boolean blankLine2 = 678 | lineBreak2 && diff_regExMatch(two, &blankLineStartRegEx); 679 | 680 | if (blankLine1 || blankLine2) { 681 | // Five points for blank lines. 682 | return 5; 683 | } else if (lineBreak1 || lineBreak2) { 684 | // Four points for line breaks. 685 | return 4; 686 | } else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) { 687 | // Three points for end of sentences. 688 | return 3; 689 | } else if (whitespace1 || whitespace2) { 690 | // Two points for whitespace. 691 | return 2; 692 | } else if (nonAlphaNumeric1 || nonAlphaNumeric2) { 693 | // One point for non-alphanumeric. 694 | return 1; 695 | } 696 | return 0; 697 | } 698 | -------------------------------------------------------------------------------- /DiffMatchPatchCFUtilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #ifndef _DIFFMATCHPATCHCFUTILITIES_H 24 | #define _DIFFMATCHPATCHCFUTILITIES_H 25 | 26 | CFStringRef diff_CFStringCreateFromUnichar(UniChar ch); 27 | 28 | CF_INLINE CFStringRef diff_CFStringCreateSubstring(CFStringRef text, CFIndex start_index, CFIndex length) { 29 | CFRange substringRange = { 30 | .length = length, 31 | .location = start_index, 32 | }; 33 | 34 | CFStringRef substring = CFStringCreateWithSubstring(kCFAllocatorDefault, text, substringRange); 35 | 36 | return substring; 37 | } 38 | 39 | CF_INLINE CFStringRef diff_CFStringCreateRightSubstring(CFStringRef text, CFIndex text_length, CFIndex new_length) { 40 | return diff_CFStringCreateSubstring(text, text_length - new_length, new_length); 41 | } 42 | 43 | CF_INLINE CFStringRef diff_CFStringCreateLeftSubstring(CFStringRef text, CFIndex new_length) { 44 | return diff_CFStringCreateSubstring(text, 0, new_length); 45 | } 46 | 47 | CF_INLINE CFStringRef diff_CFStringCreateSubstringWithStartIndex(CFStringRef text, CFIndex start_index) { 48 | return diff_CFStringCreateSubstring(text, start_index, (CFStringGetLength(text) - start_index)); 49 | } 50 | 51 | CF_INLINE CFStringRef diff_CFStringCreateJavaSubstring(CFStringRef s, CFIndex begin, CFIndex end) { 52 | return diff_CFStringCreateSubstring(s, begin, end - begin); 53 | } 54 | 55 | CFIndex diff_commonPrefix(CFStringRef text1, CFStringRef text2); 56 | CFIndex diff_commonSuffix(CFStringRef text1, CFStringRef text2); 57 | CFIndex diff_commonOverlap(CFStringRef text1, CFStringRef text2); 58 | CFArrayRef diff_halfMatchCreate(CFStringRef text1, CFStringRef text2, const float diffTimeout); 59 | CFArrayRef diff_halfMatchICreate(CFStringRef longtext, CFStringRef shorttext, CFIndex i); 60 | 61 | CFStringRef diff_linesToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef lineArray, CFMutableDictionaryRef lineHash); 62 | CFStringRef diff_tokensToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash, CFOptionFlags tokenizerOptions); 63 | CFStringRef diff_wordsToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash); 64 | CFStringRef diff_sentencesToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash); 65 | CFStringRef diff_paragraphsToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash); 66 | CFStringRef diff_lineBreakDelimiteredToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef tokenArray, CFMutableDictionaryRef tokenHash); 67 | CFStringRef diff_rangesToCharsMungeCFStringCreate(CFStringRef text, CFMutableArrayRef substringArray, CFMutableDictionaryRef substringHash, CFRange *ranges, size_t ranges_count); 68 | 69 | CFStringRef diff_charsToTokenCFStringCreate(CFStringRef charsString, CFArrayRef tokenArray); 70 | 71 | CFIndex diff_cleanupSemanticScore(CFStringRef one, CFStringRef two); 72 | 73 | CF_INLINE void diff_CFStringPrepareUniCharBuffer(CFStringRef string, const UniChar **string_chars, UniChar **string_buffer, CFRange string_range) { 74 | *string_chars = CFStringGetCharactersPtr(string); 75 | if (*string_chars == NULL) { 76 | // Fallback in case CFStringGetCharactersPtr() didn’t work. 77 | *string_buffer = malloc(string_range.length * sizeof(UniChar)); 78 | CFStringGetCharacters(string, string_range, *string_buffer); 79 | *string_chars = *string_buffer; 80 | } 81 | } 82 | 83 | #define CFIndexArrayLastValueIndex (CFArrayGetCount(theArray)-1) 84 | 85 | CF_INLINE CFIndex diff_CFArrayLastValueAsCFIndex(CFMutableArrayRef theArray) { 86 | return (CFIndex)CFArrayGetValueAtIndex(theArray, CFIndexArrayLastValueIndex); 87 | } 88 | 89 | CF_INLINE void diff_CFArrayRemoveLastValue(CFMutableArrayRef theArray) { 90 | CFArrayRemoveValueAtIndex(theArray, CFIndexArrayLastValueIndex); 91 | } 92 | 93 | #undef CFIndexArrayLastValueIndex 94 | 95 | #endif //ifndef _DIFFMATCHPATCHCFUTILITIES_H 96 | -------------------------------------------------------------------------------- /DiffMatchPatch_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'DiffMatchPatch' target in the 'DiffMatchPatch' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Google-diff-Match-Patch.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "Google-Diff-Match-Patch" 3 | s.version = "1.0.6" 4 | s.summary = "The Diff Match and Patch libraries offer robust algorithms to perform the operations required for synchronizing plain text." 5 | s.homepage = "http://code.google.com/p/google-diff-match-patch/" 6 | 7 | s.license = { :type => 'Apache License, Version 2.0', :file => 'COPYING' } 8 | s.authors = { 'Neil Fraser' => 'fraser@google.com', 'Jan Weiß' => 'jan@geheimwerk.de' } 9 | 10 | Pod::Specs.source = { :git => "https://github.com/JanX2/google-diff-match-patch-Objective-C.git", :tag => "v1.0.6" } 11 | 12 | s.ios.deployment_target = '4.0' 13 | s.osx.deployment_target = '10.6' 14 | 15 | s.source_files = '*.{h,m,c}' 16 | 17 | s.requires_arc = false 18 | end -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 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 | FMWK 19 | CFBundleShortVersionString 20 | ${MARKETING_VERSION} 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | ${PROJECT_VERSION} 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /JXArcCompatibilityMacros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * JXArcCompatibilityMacros.h 3 | * 4 | * Created by Jan on 29.09.12. 5 | * Copyright 2012-2013 Jan Weiß 6 | * 7 | * Based on “DDMathParser.h” by Dave DeLong. 8 | * 9 | * Released under the BSD software licence and the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * 21 | * Author: jan@geheimwerk.de (Jan Weiß) 22 | */ 23 | 24 | 25 | #ifndef JXArcCompatibilityMacros_h 26 | #define JXArcCompatibilityMacros_h 27 | 28 | #ifdef __clang__ 29 | #define JX_STRONG strong 30 | #else 31 | #define JX_STRONG retain 32 | #endif 33 | 34 | /* 35 | Porting help (pretty crude, could use improvement): 36 | \[(.+) retain\] JX_RETAIN(\1) 37 | \[(.+) release\] JX_RELEASE(\1) 38 | \[(.+) autorelease\] JX_AUTORELEASE(\1) 39 | 40 | \(id\)([\w\d.]+|\[.+\]) JX_BRIDGED_CAST(id, \1) 41 | 42 | \(__bridge ((CF|NS)\w+(\ \*)?)\)(\w+) JX_BRIDGED_CAST(\1, \4) 43 | 44 | The above have usual problems with nesting. Don’t use them with “Replace all”! 45 | */ 46 | 47 | #if __has_feature(objc_arc) 48 | 49 | #define JX_HAS_ARC 1 50 | #define JX_RETAIN(_o) (_o) 51 | #define JX_RELEASE(_o) 52 | #define JX_AUTORELEASE(_o) (_o) 53 | 54 | #define JX_BRIDGED_CAST(_type, _o) (__bridge _type)(_o) 55 | #define JX_TRANSFER_OBJC_TO_CF(_type, _o) (__bridge_retained _type)(_o) 56 | #define JX_TRANSFER_CF_TO_OBJC(_type, _o) (__bridge_transfer _type)(_o) 57 | 58 | #else 59 | 60 | #define JX_HAS_ARC 0 61 | #define JX_RETAIN(_o) [(_o) retain] 62 | #define JX_RELEASE(_o) [(_o) release] 63 | #define JX_AUTORELEASE(_o) [(_o) autorelease] 64 | 65 | #define JX_BRIDGED_CAST(_type, _o) (_type)(_o) 66 | #define JX_TRANSFER_OBJC_TO_CF(_type, _o) (_type)((_o) ? CFRetain((CFTypeRef)(_o)) : NULL) 67 | #define JX_TRANSFER_CF_TO_OBJC(_type, _o) [(_type)CFMakeCollectable(_o) autorelease] 68 | 69 | #endif 70 | 71 | 72 | #ifdef __clang__ 73 | 74 | #define JX_NEW_AUTORELEASE_POOL_WITH_NAME(_o) @autoreleasepool { 75 | #define JX_END_AUTORELEASE_POOL_WITH_NAME(_o) } 76 | 77 | #define JX_DRAIN_AUTORELEASE_POOL_WITH_NAME(_o) 78 | 79 | #else 80 | 81 | #define JX_NEW_AUTORELEASE_POOL_WITH_NAME(_o) NSAutoreleasePool *(_o) = [NSAutoreleasePool new]; 82 | #define JX_END_AUTORELEASE_POOL_WITH_NAME(_o) [(_o) drain]; 83 | 84 | #define JX_DRAIN_AUTORELEASE_POOL_WITH_NAME(_o) [(_o) drain] 85 | 86 | #endif 87 | 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /MinMaxMacros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #if !defined(MIN) 24 | #define MIN(A,B) \ 25 | ({__typeof__(A) a = (A); \ 26 | __typeof__(B) b = (B); \ 27 | (a < b) ? a : b; }) 28 | #endif 29 | 30 | #if !defined(MAX) 31 | #define MAX(A,B) \ 32 | ({__typeof__(A) a = (A); \ 33 | __typeof__(B) b = (B); \ 34 | (a > b) ? a : b; }) 35 | #endif 36 | 37 | #if !defined(ABS) 38 | #define ABS(A) \ 39 | ({__typeof__(A) a = (A); \ 40 | (a > 0) ? a : -a; }) 41 | #endif 42 | -------------------------------------------------------------------------------- /NSMutableDictionary+DMPExtensions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import 24 | 25 | 26 | @interface NSMutableDictionary (DMPExtensions) 27 | 28 | - (id)diff_objectForIntegerKey:(NSInteger)keyInteger; 29 | - (id)diff_objectForUnsignedIntegerKey:(NSUInteger)keyUInteger; 30 | - (id)diff_objectForUnicharKey:(unichar)aUnicharKey; 31 | 32 | - (NSInteger)diff_integerForKey:(id)aKey; 33 | - (NSUInteger)diff_unsignedIntegerForKey:(id)aKey; 34 | - (NSInteger)diff_integerForIntegerKey:(NSInteger)keyInteger; 35 | - (NSUInteger)diff_unsignedIntegerForUnicharKey:(unichar)aUnicharKey; 36 | 37 | - (BOOL)diff_containsObjectForKey:(id)aKey; 38 | - (BOOL)diff_containsObjectForUnicharKey:(unichar)aUnicharKey; 39 | 40 | - (void)diff_setIntegerValue:(NSInteger)anInteger forKey:(id)aKey; 41 | - (void)diff_setIntegerValue:(NSInteger)anInteger forIntegerKey:(NSInteger)keyInteger; 42 | 43 | - (void)diff_setUnsignedIntegerValue:(NSUInteger)anUInteger forKey:(id)aKey; 44 | - (void)diff_setUnsignedIntegerValue:(NSUInteger)anUInteger forUnsignedIntegerKey:(NSUInteger)keyUInteger; 45 | - (void)diff_setUnsignedIntegerValue:(NSUInteger)anUInteger forUnicharKey:(unichar)aUnicharKey; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /NSMutableDictionary+DMPExtensions.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import "NSMutableDictionary+DMPExtensions.h" 24 | 25 | #import "NSString+UnicharUtilities.h" 26 | 27 | 28 | @implementation NSMutableDictionary (DMPExtensions) 29 | 30 | - (id)diff_objectForIntegerKey:(NSInteger)keyInteger; 31 | { 32 | return [self objectForKey:[NSNumber numberWithInteger:keyInteger]]; 33 | } 34 | 35 | - (id)diff_objectForUnsignedIntegerKey:(NSUInteger)keyUInteger; 36 | { 37 | return [self objectForKey:[NSNumber numberWithUnsignedInteger:keyUInteger]]; 38 | } 39 | 40 | - (id)diff_objectForUnicharKey:(unichar)aUnicharKey; 41 | { 42 | return [self objectForKey:[NSString diff_stringFromUnichar:aUnicharKey]]; 43 | } 44 | 45 | 46 | - (NSInteger)diff_integerForKey:(id)aKey; 47 | { 48 | return [((NSNumber *)[self objectForKey:aKey]) integerValue]; 49 | } 50 | 51 | - (NSUInteger)diff_unsignedIntegerForKey:(id)aKey; 52 | { 53 | return [((NSNumber *)[self objectForKey:aKey]) unsignedIntegerValue]; 54 | } 55 | 56 | - (NSInteger)diff_integerForIntegerKey:(NSInteger)keyInteger; 57 | { 58 | return [((NSNumber *)[self objectForKey:[NSNumber numberWithInteger:keyInteger]]) integerValue]; 59 | } 60 | 61 | - (NSUInteger)diff_unsignedIntegerForUnicharKey:(unichar)aUnicharKey; 62 | { 63 | return [((NSNumber *)[self diff_objectForUnicharKey:aUnicharKey]) unsignedIntegerValue]; 64 | } 65 | 66 | 67 | - (BOOL)diff_containsObjectForKey:(id)aKey; 68 | { 69 | return ([self objectForKey:aKey] != nil); 70 | } 71 | 72 | - (BOOL)containsObjectForIntegerKey:(NSInteger)keyInteger; 73 | { 74 | return ([self objectForKey:[NSNumber numberWithInteger:keyInteger]] != nil); 75 | } 76 | 77 | - (BOOL)diff_containsObjectForUnicharKey:(unichar)aUnicharKey; 78 | { 79 | return ([self diff_objectForUnicharKey:aUnicharKey] != nil); 80 | } 81 | 82 | 83 | - (void)diff_setIntegerValue:(NSInteger)anInteger forKey:(id)aKey; 84 | { 85 | [self setObject:[NSNumber numberWithInteger:anInteger] forKey:aKey]; 86 | } 87 | 88 | - (void)diff_setIntegerValue:(NSInteger)anInteger forIntegerKey:(NSInteger)keyInteger; 89 | { 90 | [self setObject:[NSNumber numberWithInteger:anInteger] forKey:[NSNumber numberWithInteger:keyInteger]]; 91 | } 92 | 93 | 94 | - (void)diff_setUnsignedIntegerValue:(NSUInteger)anUInteger forKey:(id)aKey; 95 | { 96 | [self setObject:[NSNumber numberWithUnsignedInteger:anUInteger] forKey:aKey]; 97 | } 98 | 99 | - (void)diff_setUnsignedIntegerValue:(NSUInteger)anUInteger forUnsignedIntegerKey:(NSUInteger)keyUInteger; 100 | { 101 | [self setObject:[NSNumber numberWithUnsignedInteger:anUInteger] forKey:[NSNumber numberWithUnsignedInteger:keyUInteger]]; 102 | } 103 | 104 | - (void)diff_setUnsignedIntegerValue:(NSUInteger)anUInteger forUnicharKey:(unichar)aUnicharKey; 105 | { 106 | [self setObject:[NSNumber numberWithUnsignedInteger:anUInteger] forKey:[NSString diff_stringFromUnichar:aUnicharKey]]; 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /NSString+JavaSubstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import 24 | 25 | 26 | @interface NSString (JavaSubstring) 27 | 28 | - (NSString *)diff_javaSubstringFromStart:(NSUInteger)start toEnd:(NSUInteger)end; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /NSString+JavaSubstring.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import "NSString+JavaSubstring.h" 24 | 25 | #import "DiffMatchPatchCFUtilities.h" 26 | #import "JXArcCompatibilityMacros.h" 27 | 28 | @implementation NSString (JavaSubstring) 29 | 30 | - (NSString *)diff_javaSubstringFromStart:(NSUInteger)start toEnd:(NSUInteger)end; 31 | { 32 | CFStringRef c = diff_CFStringCreateJavaSubstring(JX_BRIDGED_CAST(CFStringRef, self), (CFIndex)start, (CFIndex)end); 33 | return JX_TRANSFER_CF_TO_OBJC(NSString *, c); 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /NSString+UnicharUtilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import 24 | 25 | 26 | @interface NSString (UnicharUtilities) 27 | 28 | + (NSString *)diff_stringFromUnichar:(unichar)ch; 29 | - (NSString *)diff_substringWithCharacterAtIndex:(NSUInteger)anIndex; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /NSString+UnicharUtilities.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import "NSString+UnicharUtilities.h" 24 | #import "JXArcCompatibilityMacros.h" 25 | 26 | 27 | @implementation NSString (UnicharUtilities) 28 | 29 | + (NSString *)diff_stringFromUnichar:(unichar)ch; 30 | { 31 | CFStringRef c = CFStringCreateWithCharacters(kCFAllocatorDefault, &ch, 1); 32 | return JX_TRANSFER_CF_TO_OBJC(NSString *, c); 33 | } 34 | 35 | - (NSString *)diff_substringWithCharacterAtIndex:(NSUInteger)anIndex; 36 | { 37 | return [self substringWithRange:NSMakeRange(anIndex, 1)]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /NSString+UriCompatibility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import 24 | 25 | 26 | @interface NSString (UriCompatibility) 27 | 28 | - (NSString *)diff_stringByAddingPercentEscapesForEncodeUriCompatibility; 29 | - (NSString *)diff_stringByReplacingPercentEscapesForEncodeUriCompatibility; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /NSString+UriCompatibility.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import "NSString+UriCompatibility.h" 24 | #import "JXArcCompatibilityMacros.h" 25 | 26 | 27 | @implementation NSString (UriCompatibility) 28 | 29 | /** 30 | * Escape excluding selected chars for compatability with JavaScript's encodeURI. 31 | * This method produces uppercase hex. 32 | * 33 | * @param str The CFStringRef to escape. 34 | * @return The escaped CFStringRef. 35 | */ 36 | - (NSString *)diff_stringByAddingPercentEscapesForEncodeUriCompatibility; 37 | { 38 | CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(NULL, 39 | JX_BRIDGED_CAST(CFStringRef, self), 40 | CFSTR(" !~*'();/?:@&=+$,#"), 41 | NULL, 42 | kCFStringEncodingUTF8); 43 | return JX_TRANSFER_CF_TO_OBJC(NSString *, urlString); 44 | } 45 | 46 | /** 47 | * Unescape all percent escapes. 48 | * 49 | * Example: "%3f" -> "?", "%24" -> "$", etc. 50 | * 51 | * @return The unescaped NSString. 52 | */ 53 | - (NSString *)diff_stringByReplacingPercentEscapesForEncodeUriCompatibility; 54 | { 55 | CFStringRef decodedString = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, 56 | JX_BRIDGED_CAST(CFStringRef, self), 57 | CFSTR(""), 58 | kCFStringEncodingUTF8); 59 | return JX_TRANSFER_CF_TO_OBJC(NSString *, decodedString); 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | Diff, Match and Patch Library, Objective C port 2 | =============================================== 3 | 4 | 5 | 6 | ## Diff, Match and Patch library for plain text 7 | 8 | The Diff Match and Patch libraries offer robust algorithms to perform 9 | the operations required for synchronizing plain text. 10 | 11 | ### Diff: 12 | 13 | - Compare two blocks of plain text and efficiently return a list of 14 | differences. 15 | - [Diff 16 | Demo](http://neil.fraser.name/software/diff_match_patch/svn/trunk/demos/demo_diff.html) 17 | 18 | ### Match: 19 | 20 | - Given a search string, find its best fuzzy match in a block of plain 21 | text. Weighted for both accuracy and location. 22 | - [Match 23 | Demo](http://neil.fraser.name/software/diff_match_patch/svn/trunk/demos/demo_match.html) 24 | 25 | ### Patch: 26 | 27 | - Apply a list of patches onto plain text. Use best-effort to apply 28 | patch even when the underlying text doesn't match. 29 | - [Patch 30 | Demo](http://neil.fraser.name/software/diff_match_patch/svn/trunk/demos/demo_patch.html) 31 | 32 | Currently available in Java, JavaScript, Dart, C++, C\#, Objective C, 33 | Lua and Python. Regardless of language, each library features [the same 34 | API](http://code.google.com/p/google-diff-match-patch/wiki/API) and the 35 | same functionality. All versions also have comprehensive test harnesses. 36 | 37 | ### Algorithms 38 | 39 | This library implements [Myer's diff 40 | algorithm](http://neil.fraser.name/software/diff_match_patch/myers.pdf) 41 | which is generally considered to be the best general-purpose diff. A 42 | layer of [pre-diff speedups and post-diff 43 | cleanups](http://neil.fraser.name/writing/diff/) surround the diff 44 | algorithm, improving both performance and output quality. 45 | 46 | This library also implements a [Bitap matching 47 | algorithm](http://neil.fraser.name/software/diff_match_patch/bitap.ps) 48 | at the heart of a flexible [matching and patching 49 | strategy](http://neil.fraser.name/writing/patch/). 50 | 51 | Usage 52 | ----- 53 | 54 | Add “DiffMatchPatch.xcodeproj” to your project (preferably into “Frameworks” to keep things tidy). 55 | 56 | In your target’s “Build Phases”: 57 | 58 | * Add Build Phase (+-button pull-down menu) > Copy Files 59 | * Destination: Frameworks 60 | * Change name to “Copy Frameworks” to keep things clean 61 | 62 | Add “DiffMatchPatch.framework” to the following build phases (via the +-buttons): 63 | 64 | * “Target Dependencies” 65 | * “Link Binary With Libraries” 66 | * “Copy Frameworks” (created above) 67 | 68 | And finally add the header to your code: 69 | 70 | #import 71 | 72 | 73 | Notes 74 | ----- 75 | 76 | If you want to run the speed test, you first need to change the working directory of the executable “speedtest” to “Project directory”. This cannot be done beforehand, because this setting is stored in the current user’s project settings. -------------------------------------------------------------------------------- /Speedtest1.txt: -------------------------------------------------------------------------------- 1 | This is a '''list of newspapers published by [[Journal Register Company]]'''. 2 | 3 | The company owns daily and weekly newspapers, other print media properties and newspaper-affiliated local Websites in the [[U.S.]] states of [[Connecticut]], [[Michigan]], [[New York]], [[Ohio]] and [[Pennsylvania]], organized in six geographic "clusters":[http://www.journalregister.com/newspapers.html Journal Register Company: Our Newspapers], accessed February 10, 2008. 4 | 5 | == Capital-Saratoga == 6 | Three dailies, associated weeklies and [[pennysaver]]s in greater [[Albany, New York]]; also [http://www.capitalcentral.com capitalcentral.com] and [http://www.jobsinnewyork.com JobsInNewYork.com]. 7 | 8 | * ''The Oneida Daily Dispatch'' {{WS|oneidadispatch.com}} of [[Oneida, New York]] 9 | * ''[[The Record (Troy)|The Record]]'' {{WS|troyrecord.com}} of [[Troy, New York]] 10 | * ''[[The Saratogian]]'' {{WS|saratogian.com}} of [[Saratoga Springs, New York]] 11 | * Weeklies: 12 | ** ''Community News'' {{WS|cnweekly.com}} weekly of [[Clifton Park, New York]] 13 | ** ''Rome Observer'' of [[Rome, New York]] 14 | ** ''Life & Times of Utica'' of [[Utica, New York]] 15 | 16 | == Connecticut == 17 | Five dailies, associated weeklies and [[pennysaver]]s in the state of [[Connecticut]]; also [http://www.ctcentral.com CTcentral.com], [http://www.ctcarsandtrucks.com CTCarsAndTrucks.com] and [http://www.jobsinct.com JobsInCT.com]. 18 | 19 | * ''The Middletown Press'' {{WS|middletownpress.com}} of [[Middletown, Connecticut|Middletown]] 20 | * ''[[New Haven Register]]'' {{WS|newhavenregister.com}} of [[New Haven, Connecticut|New Haven]] 21 | * ''The Register Citizen'' {{WS|registercitizen.com}} of [[Torrington, Connecticut|Torrington]] 22 | 23 | * [[New Haven Register#Competitors|Elm City Newspapers]] {{WS|ctcentral.com}} 24 | ** ''The Advertiser'' of [[East Haven, Connecticut|East Haven]] 25 | ** ''Hamden Chronicle'' of [[Hamden, Connecticut|Hamden]] 26 | ** ''Milford Weekly'' of [[Milford, Connecticut|Milford]] 27 | ** ''The Orange Bulletin'' of [[Orange, Connecticut|Orange]] 28 | ** ''The Post'' of [[North Haven, Connecticut|North Haven]] 29 | ** ''Shelton Weekly'' of [[Shelton, Connecticut|Shelton]] 30 | ** ''The Stratford Bard'' of [[Stratford, Connecticut|Stratford]] 31 | ** ''Wallingford Voice'' of [[Wallingford, Connecticut|Wallingford]] 32 | ** ''West Haven News'' of [[West Haven, Connecticut|West Haven]] 33 | * Housatonic Publications 34 | ** ''The New Milford Times'' {{WS|newmilfordtimes.com}} of [[New Milford, Connecticut|New Milford]] 35 | ** ''The Brookfield Journal'' of [[Brookfield, Connecticut|Brookfield]] 36 | ** ''The Kent Good Times Dispatch'' of [[Kent, Connecticut|Kent]] 37 | ** ''The Bethel Beacon'' of [[Bethel, Connecticut|Bethel]] 38 | ** ''The Litchfield Enquirer'' of [[Litchfield, Connecticut|Litchfield]] 39 | ** ''Litchfield County Times'' of [[Litchfield, Connecticut|Litchfield]] 40 | * Imprint Newspapers {{WS|imprintnewspapers.com}} 41 | ** ''West Hartford News'' of [[West Hartford, Connecticut|West Hartford]] 42 | ** ''Windsor Journal'' of [[Windsor, Connecticut|Windsor]] 43 | ** ''Windsor Locks Journal'' of [[Windsor Locks, Connecticut|Windsor Locks]] 44 | ** ''Avon Post'' of [[Avon, Connecticut|Avon]] 45 | ** ''Farmington Post'' of [[Farmington, Connecticut|Farmington]] 46 | ** ''Simsbury Post'' of [[Simsbury, Connecticut|Simsbury]] 47 | ** ''Tri-Town Post'' of [[Burlington, Connecticut|Burlington]], [[Canton, Connecticut|Canton]] and [[Harwinton, Connecticut|Harwinton]] 48 | * Minuteman Publications 49 | ** ''[[Fairfield Minuteman]]'' of [[Fairfield, Connecticut|Fairfield]] 50 | ** ''The Westport Minuteman'' {{WS|westportminuteman.com}} of [[Westport, Connecticut|Westport]] 51 | * Shoreline Newspapers weeklies: 52 | ** ''Branford Review'' of [[Branford, Connecticut|Branford]] 53 | ** ''Clinton Recorder'' of [[Clinton, Connecticut|Clinton]] 54 | ** ''The Dolphin'' of [[Naval Submarine Base New London]] in [[New London, Connecticut|New London]] 55 | ** ''Main Street News'' {{WS|ctmainstreetnews.com}} of [[Essex, Connecticut|Essex]] 56 | ** ''Pictorial Gazette'' of [[Old Saybrook, Connecticut|Old Saybrook]] 57 | ** ''Regional Express'' of [[Colchester, Connecticut|Colchester]] 58 | ** ''Regional Standard'' of [[Colchester, Connecticut|Colchester]] 59 | ** ''Shoreline Times'' {{WS|shorelinetimes.com}} of [[Guilford, Connecticut|Guilford]] 60 | ** ''Shore View East'' of [[Madison, Connecticut|Madison]] 61 | ** ''Shore View West'' of [[Guilford, Connecticut|Guilford]] 62 | * Other weeklies: 63 | ** ''Registro'' {{WS|registroct.com}} of [[New Haven, Connecticut|New Haven]] 64 | ** ''Thomaston Express'' {{WS|thomastownexpress.com}} of [[Thomaston, Connecticut|Thomaston]] 65 | ** ''Foothills Traders'' {{WS|foothillstrader.com}} of Torrington, Bristol, Canton 66 | 67 | == Michigan == 68 | Four dailies, associated weeklies and [[pennysaver]]s in the state of [[Michigan]]; also [http://www.micentralhomes.com MIcentralhomes.com] and [http://www.micentralautos.com MIcentralautos.com] 69 | * ''[[Oakland Press]]'' {{WS|theoaklandpress.com}} of [[Oakland, Michigan|Oakland]] 70 | * ''Daily Tribune'' {{WS|dailytribune.com}} of [[Royal Oak, Michigan|Royal Oak]] 71 | * ''Macomb Daily'' {{WS|macombdaily.com}} of [[Mt. Clemens, Michigan|Mt. Clemens]] 72 | * ''[[Morning Sun]]'' {{WS|themorningsun.com}} of [[Mount Pleasant, Michigan|Mount Pleasant]] 73 | * Heritage Newspapers {{WS|heritage.com}} 74 | ** ''Belleville View'' 75 | ** ''Ile Camera'' 76 | ** ''Monroe Guardian'' 77 | ** ''Ypsilanti Courier'' 78 | ** ''News-Herald'' 79 | ** ''Press & Guide'' 80 | ** ''Chelsea Standard & Dexter Leader'' 81 | ** ''Manchester Enterprise'' 82 | ** ''Milan News-Leader'' 83 | ** ''Saline Reporter'' 84 | * Independent Newspapers {{WS|sourcenewspapers.com}} 85 | ** ''Advisor'' 86 | ** ''Source'' 87 | * Morning Star {{WS|morningstarpublishing.com}} 88 | ** ''Alma Reminder'' 89 | ** ''Alpena Star'' 90 | ** ''Antrim County News'' 91 | ** ''Carson City Reminder'' 92 | ** ''The Leader & Kalkaskian'' 93 | ** ''Ogemaw/Oscoda County Star'' 94 | ** ''Petoskey/Charlevoix Star'' 95 | ** ''Presque Isle Star'' 96 | ** ''Preview Community Weekly'' 97 | ** ''Roscommon County Star'' 98 | ** ''St. Johns Reminder'' 99 | ** ''Straits Area Star'' 100 | ** ''The (Edmore) Advertiser'' 101 | * Voice Newspapers {{WS|voicenews.com}} 102 | ** ''Armada Times'' 103 | ** ''Bay Voice'' 104 | ** ''Blue Water Voice'' 105 | ** ''Downriver Voice'' 106 | ** ''Macomb Township Voice'' 107 | ** ''North Macomb Voice'' 108 | ** ''Weekend Voice'' 109 | ** ''Suburban Lifestyles'' {{WS|suburbanlifestyles.com}} 110 | 111 | == Mid-Hudson == 112 | One daily, associated magazines in the [[Hudson River Valley]] of [[New York]]; also [http://www.midhudsoncentral.com MidHudsonCentral.com] and [http://www.jobsinnewyork.com JobsInNewYork.com]. 113 | 114 | * ''[[Daily Freeman]]'' {{WS|dailyfreeman.com}} of [[Kingston, New York]] 115 | 116 | == Ohio == 117 | Two dailies, associated magazines and three shared Websites, all in the state of [[Ohio]]: [http://www.allaroundcleveland.com AllAroundCleveland.com], [http://www.allaroundclevelandcars.com AllAroundClevelandCars.com] and [http://www.allaroundclevelandjobs.com AllAroundClevelandJobs.com]. 118 | 119 | * ''[[The News-Herald (Ohio)|The News-Herald]]'' {{WS|news-herald.com}} of [[Willoughby, Ohio|Willoughby]] 120 | * ''[[The Morning Journal]]'' {{WS|morningjournal.com}} of [[Lorain, Ohio|Lorain]] 121 | 122 | == Philadelphia area == 123 | Seven dailies and associated weeklies and magazines in [[Pennsylvania]] and [[New Jersey]], and associated Websites: [http://www.allaroundphilly.com AllAroundPhilly.com], [http://www.jobsinnj.com JobsInNJ.com], [http://www.jobsinpa.com JobsInPA.com], and [http://www.phillycarsearch.com PhillyCarSearch.com]. 124 | 125 | * ''The Daily Local'' {{WS|dailylocal.com}} of [[West Chester, Pennsylvania|West Chester]] 126 | * ''[[Delaware County Daily and Sunday Times]] {{WS|delcotimes.com}} of Primos 127 | * ''[[The Mercury (Pennsylvania)|The Mercury]]'' {{WS|pottstownmercury.com}} of [[Pottstown, Pennsylvania|Pottstown]] 128 | * ''The Phoenix'' {{WS|phoenixvillenews.com}} of [[Phoenixville, Pennsylvania|Phoenixville]] 129 | * ''[[The Reporter (Lansdale)|The Reporter]]'' {{WS|thereporteronline.com}} of [[Lansdale, Pennsylvania|Lansdale]] 130 | * ''The Times Herald'' {{WS|timesherald.com}} of [[Norristown, Pennsylvania|Norristown]] 131 | * ''[[The Trentonian]]'' {{WS|trentonian.com}} of [[Trenton, New Jersey]] 132 | 133 | * Weeklies 134 | ** ''El Latino Expreso'' of [[Trenton, New Jersey]] 135 | ** ''La Voz'' of [[Norristown, Pennsylvania]] 136 | ** ''The Village News'' of [[Downingtown, Pennsylvania]] 137 | ** ''The Times Record'' of [[Kennett Square, Pennsylvania]] 138 | ** ''The Tri-County Record'' {{WS|tricountyrecord.com}} of [[Morgantown, Pennsylvania]] 139 | ** ''News of Delaware County'' {{WS|newsofdelawarecounty.com}}of [[Havertown, Pennsylvania]] 140 | ** ''Main Line Times'' {{WS|mainlinetimes.com}}of [[Ardmore, Pennsylvania]] 141 | ** ''Penny Pincher'' of [[Pottstown, Pennsylvania]] 142 | ** ''Town Talk'' {{WS|towntalknews.com}} of [[Ridley, Pennsylvania]] 143 | * Chesapeake Publishing {{WS|pa8newsgroup.com}} 144 | ** ''Solanco Sun Ledger'' of [[Quarryville, Pennsylvania]] 145 | ** ''Columbia Ledger'' of [[Columbia, Pennsylvania]] 146 | ** ''Coatesville Ledger'' of [[Downingtown, Pennsylvania]] 147 | ** ''Parkesburg Post Ledger'' of [[Quarryville, Pennsylvania]] 148 | ** ''Downingtown Ledger'' of [[Downingtown, Pennsylvania]] 149 | ** ''The Kennett Paper'' of [[Kennett Square, Pennsylvania]] 150 | ** ''Avon Grove Sun'' of [[West Grove, Pennsylvania]] 151 | ** ''Oxford Tribune'' of [[Oxford, Pennsylvania]] 152 | ** ''Elizabethtown Chronicle'' of [[Elizabethtown, Pennsylvania]] 153 | ** ''Donegal Ledger'' of [[Donegal, Pennsylvania]] 154 | ** ''Chadds Ford Post'' of [[Chadds Ford, Pennsylvania]] 155 | ** ''The Central Record'' of [[Medford, New Jersey]] 156 | ** ''Maple Shade Progress'' of [[Maple Shade, New Jersey]] 157 | * Intercounty Newspapers {{WS|buckslocalnews.com}} 158 | ** ''The Review'' of Roxborough, Pennsylvania 159 | ** ''The Recorder'' of [[Conshohocken, Pennsylvania]] 160 | ** ''The Leader'' of [[Mount Airy, Pennsylvania|Mount Airy]] and West Oak Lake, Pennsylvania 161 | ** ''The Pennington Post'' of [[Pennington, New Jersey]] 162 | ** ''The Bristol Pilot'' of [[Bristol, Pennsylvania]] 163 | ** ''Yardley News'' of [[Yardley, Pennsylvania]] 164 | ** ''New Hope Gazette'' of [[New Hope, Pennsylvania]] 165 | ** ''Doylestown Patriot'' of [[Doylestown, Pennsylvania]] 166 | ** ''Newtown Advance'' of [[Newtown, Pennsylvania]] 167 | ** ''The Plain Dealer'' of [[Williamstown, New Jersey]] 168 | ** ''News Report'' of [[Sewell, New Jersey]] 169 | ** ''Record Breeze'' of [[Berlin, New Jersey]] 170 | ** ''Newsweekly'' of [[Moorestown, New Jersey]] 171 | ** ''Haddon Herald'' of [[Haddonfield, New Jersey]] 172 | ** ''New Egypt Press'' of [[New Egypt, New Jersey]] 173 | ** ''Community News'' of [[Pemberton, New Jersey]] 174 | ** ''Plymouth Meeting Journal'' of [[Plymouth Meeting, Pennsylvania]] 175 | ** ''Lafayette Hill Journal'' of [[Lafayette Hill, Pennsylvania]] 176 | * Montgomery Newspapers {{WS|montgomerynews.com}} 177 | ** ''Ambler Gazette'' of [[Ambler, Pennsylvania]] 178 | ** ''Central Bucks Life'' of [[Bucks County, Pennsylvania]] 179 | ** ''The Colonial'' of [[Plymouth Meeting, Pennsylvania]] 180 | ** ''Glenside News'' of [[Glenside, Pennsylvania]] 181 | ** ''The Globe'' of [[Lower Moreland Township, Pennsylvania]] 182 | ** ''Main Line Life'' of [[Ardmore, Pennsylvania]] 183 | ** ''Montgomery Life'' of [[Fort Washington, Pennsylvania]] 184 | ** ''North Penn Life'' of [[Lansdale, Pennsylvania]] 185 | ** ''Perkasie News Herald'' of [[Perkasie, Pennsylvania]] 186 | ** ''Public Spirit'' of [[Hatboro, Pennsylvania]] 187 | ** ''Souderton Independent'' of [[Souderton, Pennsylvania]] 188 | ** ''Springfield Sun'' of [[Springfield, Pennsylvania]] 189 | ** ''Spring-Ford Reporter'' of [[Royersford, Pennsylvania]] 190 | ** ''Times Chronicle'' of [[Jenkintown, Pennsylvania]] 191 | ** ''Valley Item'' of [[Perkiomenville, Pennsylvania]] 192 | ** ''Willow Grove Guide'' of [[Willow Grove, Pennsylvania]] 193 | * News Gleaner Publications (closed December 2008) {{WS|newsgleaner.com}} 194 | ** ''Life Newspapers'' of [[Philadelphia, Pennsylvania]] 195 | * Suburban Publications 196 | ** ''The Suburban & Wayne Times'' {{WS|waynesuburban.com}} of [[Wayne, Pennsylvania]] 197 | ** ''The Suburban Advertiser'' of [[Exton, Pennsylvania]] 198 | ** ''The King of Prussia Courier'' of [[King of Prussia, Pennsylvania]] 199 | * Press Newspapers {{WS|countypressonline.com}} 200 | ** ''County Press'' of [[Newtown Square, Pennsylvania]] 201 | ** ''Garnet Valley Press'' of [[Glen Mills, Pennsylvania]] 202 | ** ''Haverford Press'' of [[Newtown Square, Pennsylvania]] (closed January 2009) 203 | ** ''Hometown Press'' of [[Glen Mills, Pennsylvania]] (closed January 2009) 204 | ** ''Media Press'' of [[Newtown Square, Pennsylvania]] (closed January 2009) 205 | ** ''Springfield Press'' of [[Springfield, Pennsylvania]] 206 | * Berks-Mont Newspapers {{WS|berksmontnews.com}} 207 | ** ''The Boyertown Area Times'' of [[Boyertown, Pennsylvania]] 208 | ** ''The Kutztown Area Patriot'' of [[Kutztown, Pennsylvania]] 209 | ** ''The Hamburg Area Item'' of [[Hamburg, Pennsylvania]] 210 | ** ''The Southern Berks News'' of [[Exeter Township, Berks County, Pennsylvania]] 211 | ** ''The Free Press'' of [[Quakertown, Pennsylvania]] 212 | ** ''The Saucon News'' of [[Quakertown, Pennsylvania]] 213 | ** ''Westside Weekly'' of [[Reading, Pennsylvania]] 214 | 215 | * Magazines 216 | ** ''Bucks Co. Town & Country Living'' 217 | ** ''Chester Co. Town & Country Living'' 218 | ** ''Montomgery Co. Town & Country Living'' 219 | ** ''Garden State Town & Country Living'' 220 | ** ''Montgomery Homes'' 221 | ** ''Philadelphia Golfer'' 222 | ** ''Parents Express'' 223 | ** ''Art Matters'' 224 | 225 | {{JRC}} 226 | 227 | ==References== 228 | 229 | 230 | [[Category:Journal Register publications|*]] 231 | -------------------------------------------------------------------------------- /Speedtest2.txt: -------------------------------------------------------------------------------- 1 | This is a '''list of newspapers published by [[Journal Register Company]]'''. 2 | 3 | The company owns daily and weekly newspapers, other print media properties and newspaper-affiliated local Websites in the [[U.S.]] states of [[Connecticut]], [[Michigan]], [[New York]], [[Ohio]], [[Pennsylvania]] and [[New Jersey]], organized in six geographic "clusters":[http://www.journalregister.com/publications.html Journal Register Company: Our Publications], accessed April 21, 2010. 4 | 5 | == Capital-Saratoga == 6 | Three dailies, associated weeklies and [[pennysaver]]s in greater [[Albany, New York]]; also [http://www.capitalcentral.com capitalcentral.com] and [http://www.jobsinnewyork.com JobsInNewYork.com]. 7 | 8 | * ''The Oneida Daily Dispatch'' {{WS|oneidadispatch.com}} of [[Oneida, New York]] 9 | * ''[[The Record (Troy)|The Record]]'' {{WS|troyrecord.com}} of [[Troy, New York]] 10 | * ''[[The Saratogian]]'' {{WS|saratogian.com}} of [[Saratoga Springs, New York]] 11 | * Weeklies: 12 | ** ''Community News'' {{WS|cnweekly.com}} weekly of [[Clifton Park, New York]] 13 | ** ''Rome Observer'' {{WS|romeobserver.com}} of [[Rome, New York]] 14 | ** ''WG Life '' {{WS|saratogian.com/wglife/}} of [[Wilton, New York]] 15 | ** ''Ballston Spa Life '' {{WS|saratogian.com/bspalife}} of [[Ballston Spa, New York]] 16 | ** ''Greenbush Life'' {{WS|troyrecord.com/greenbush}} of [[Troy, New York]] 17 | ** ''Latham Life'' {{WS|troyrecord.com/latham}} of [[Latham, New York]] 18 | ** ''River Life'' {{WS|troyrecord.com/river}} of [[Troy, New York]] 19 | 20 | == Connecticut == 21 | Three dailies, associated weeklies and [[pennysaver]]s in the state of [[Connecticut]]; also [http://www.ctcentral.com CTcentral.com], [http://www.ctcarsandtrucks.com CTCarsAndTrucks.com] and [http://www.jobsinct.com JobsInCT.com]. 22 | 23 | * ''The Middletown Press'' {{WS|middletownpress.com}} of [[Middletown, Connecticut|Middletown]] 24 | * ''[[New Haven Register]]'' {{WS|newhavenregister.com}} of [[New Haven, Connecticut|New Haven]] 25 | * ''The Register Citizen'' {{WS|registercitizen.com}} of [[Torrington, Connecticut|Torrington]] 26 | 27 | * Housatonic Publications 28 | ** ''The Housatonic Times'' {{WS|housatonictimes.com}} of [[New Milford, Connecticut|New Milford]] 29 | ** ''Litchfield County Times'' {{WS|countytimes.com}} of [[Litchfield, Connecticut|Litchfield]] 30 | 31 | * Minuteman Publications 32 | ** ''[[Fairfield Minuteman]]'' {{WS|fairfieldminuteman.com}}of [[Fairfield, Connecticut|Fairfield]] 33 | ** ''The Westport Minuteman'' {{WS|westportminuteman.com}} of [[Westport, Connecticut|Westport]] 34 | 35 | * Shoreline Newspapers 36 | ** ''The Dolphin'' {{WS|dolphin-news.com}} of [[Naval Submarine Base New London]] in [[New London, Connecticut|New London]] 37 | ** ''Shoreline Times'' {{WS|shorelinetimes.com}} of [[Guilford, Connecticut|Guilford]] 38 | 39 | * Foothills Media Group {{WS|foothillsmediagroup.com}} 40 | ** ''Thomaston Express'' {{WS|thomastonexpress.com}} of [[Thomaston, Connecticut|Thomaston]] 41 | ** ''Good News About Torrington'' {{WS|goodnewsabouttorrington.com}} of [[Torrington, Connecticut|Torrington]] 42 | ** ''Granby News'' {{WS|foothillsmediagroup.com/granby}} of [[Granby, Connecticut|Granby]] 43 | ** ''Canton News'' {{WS|foothillsmediagroup.com/canton}} of [[Canton, Connecticut|Canton]] 44 | ** ''Avon News'' {{WS|foothillsmediagroup.com/avon}} of [[Avon, Connecticut|Avon]] 45 | ** ''Simsbury News'' {{WS|foothillsmediagroup.com/simsbury}} of [[Simsbury, Connecticut|Simsbury]] 46 | ** ''Litchfield News'' {{WS|foothillsmediagroup.com/litchfield}} of [[Litchfield, Connecticut|Litchfield]] 47 | ** ''Foothills Trader'' {{WS|foothillstrader.com}} of Torrington, Bristol, Canton 48 | 49 | * Other weeklies 50 | ** ''The Milford-Orange Bulletin'' {{WS|ctbulletin.com}} of [[Orange, Connecticut|Orange]] 51 | ** ''The Post-Chronicle'' {{WS|ctpostchronicle.com}} of [[North Haven, Connecticut|North Haven]] 52 | ** ''West Hartford News'' {{WS|westhartfordnews.com}} of [[West Hartford, Connecticut|West Hartford]] 53 | 54 | * Magazines 55 | ** ''The Connecticut Bride'' {{WS|connecticutmag.com}} 56 | ** ''Connecticut Magazine'' {{WS|theconnecticutbride.com}} 57 | ** ''Passport Magazine'' {{WS|passport-mag.com}} 58 | 59 | == Michigan == 60 | Four dailies, associated weeklies and [[pennysaver]]s in the state of [[Michigan]]; also [http://www.micentralhomes.com MIcentralhomes.com] and [http://www.micentralautos.com MIcentralautos.com] 61 | * ''[[Oakland Press]]'' {{WS|theoaklandpress.com}} of [[Oakland, Michigan|Oakland]] 62 | * ''Daily Tribune'' {{WS|dailytribune.com}} of [[Royal Oak, Michigan|Royal Oak]] 63 | * ''Macomb Daily'' {{WS|macombdaily.com}} of [[Mt. Clemens, Michigan|Mt. Clemens]] 64 | * ''[[Morning Sun]]'' {{WS|themorningsun.com}} of [[Mount Pleasant, Michigan|Mount Pleasant]] 65 | 66 | * Heritage Newspapers {{WS|heritage.com}} 67 | ** ''Belleville View'' {{WS|bellevilleview.com}} 68 | ** ''Ile Camera'' {{WS|thenewsherald.com/ile_camera}} 69 | ** ''Monroe Guardian'' {{WS|monreguardian.com}} 70 | ** ''Ypsilanti Courier'' {{WS|ypsilanticourier.com}} 71 | ** ''News-Herald'' {{WS|thenewsherald.com}} 72 | ** ''Press & Guide'' {{WS|pressandguide.com}} 73 | ** ''Chelsea Standard & Dexter Leader'' {{WS|chelseastandard.com}} 74 | ** ''Manchester Enterprise'' {{WS|manchesterguardian.com}} 75 | ** ''Milan News-Leader'' {{WS|milannews.com}} 76 | ** ''Saline Reporter'' {{WS|salinereporter.com}} 77 | * Independent Newspapers 78 | ** ''Advisor'' {{WS|sourcenewspapers.com}} 79 | ** ''Source'' {{WS|sourcenewspapers.com}} 80 | * Morning Star {{WS|morningstarpublishing.com}} 81 | ** ''The Leader & Kalkaskian'' {{WS|leaderandkalkaskian.com}} 82 | ** ''Grand Traverse Insider'' {{WS|grandtraverseinsider.com}} 83 | ** ''Alma Reminder'' 84 | ** ''Alpena Star'' 85 | ** ''Ogemaw/Oscoda County Star'' 86 | ** ''Presque Isle Star'' 87 | ** ''St. Johns Reminder'' 88 | 89 | * Voice Newspapers {{WS|voicenews.com}} 90 | ** ''Armada Times'' 91 | ** ''Bay Voice'' 92 | ** ''Blue Water Voice'' 93 | ** ''Downriver Voice'' 94 | ** ''Macomb Township Voice'' 95 | ** ''North Macomb Voice'' 96 | ** ''Weekend Voice'' 97 | 98 | == Mid-Hudson == 99 | One daily, associated magazines in the [[Hudson River Valley]] of [[New York]]; also [http://www.midhudsoncentral.com MidHudsonCentral.com] and [http://www.jobsinnewyork.com JobsInNewYork.com]. 100 | 101 | * ''[[Daily Freeman]]'' {{WS|dailyfreeman.com}} of [[Kingston, New York]] 102 | * ''Las Noticias'' {{WS|lasnoticiasny.com}} of [[Kingston, New York]] 103 | 104 | == Ohio == 105 | Two dailies, associated magazines and three shared Websites, all in the state of [[Ohio]]: [http://www.allaroundcleveland.com AllAroundCleveland.com], [http://www.allaroundclevelandcars.com AllAroundClevelandCars.com] and [http://www.allaroundclevelandjobs.com AllAroundClevelandJobs.com]. 106 | 107 | * ''[[The News-Herald (Ohio)|The News-Herald]]'' {{WS|news-herald.com}} of [[Willoughby, Ohio|Willoughby]] 108 | * ''[[The Morning Journal]]'' {{WS|morningjournal.com}} of [[Lorain, Ohio|Lorain]] 109 | * ''El Latino Expreso'' {{WS|lorainlatino.com}} of [[Lorain, Ohio|Lorain]] 110 | 111 | == Philadelphia area == 112 | Seven dailies and associated weeklies and magazines in [[Pennsylvania]] and [[New Jersey]], and associated Websites: [http://www.allaroundphilly.com AllAroundPhilly.com], [http://www.jobsinnj.com JobsInNJ.com], [http://www.jobsinpa.com JobsInPA.com], and [http://www.phillycarsearch.com PhillyCarSearch.com]. 113 | 114 | * ''[[The Daily Local News]]'' {{WS|dailylocal.com}} of [[West Chester, Pennsylvania|West Chester]] 115 | * ''[[Delaware County Daily and Sunday Times]] {{WS|delcotimes.com}} of Primos [[Upper Darby Township, Pennsylvania]] 116 | * ''[[The Mercury (Pennsylvania)|The Mercury]]'' {{WS|pottstownmercury.com}} of [[Pottstown, Pennsylvania|Pottstown]] 117 | * ''[[The Reporter (Lansdale)|The Reporter]]'' {{WS|thereporteronline.com}} of [[Lansdale, Pennsylvania|Lansdale]] 118 | * ''The Times Herald'' {{WS|timesherald.com}} of [[Norristown, Pennsylvania|Norristown]] 119 | * ''[[The Trentonian]]'' {{WS|trentonian.com}} of [[Trenton, New Jersey]] 120 | 121 | * Weeklies 122 | * ''The Phoenix'' {{WS|phoenixvillenews.com}} of [[Phoenixville, Pennsylvania]] 123 | ** ''El Latino Expreso'' {{WS|njexpreso.com}} of [[Trenton, New Jersey]] 124 | ** ''La Voz'' {{WS|lavozpa.com}} of [[Norristown, Pennsylvania]] 125 | ** ''The Tri County Record'' {{WS|tricountyrecord.com}} of [[Morgantown, Pennsylvania]] 126 | ** ''Penny Pincher'' {{WS|pennypincherpa.com}}of [[Pottstown, Pennsylvania]] 127 | 128 | * Chesapeake Publishing {{WS|southernchestercountyweeklies.com}} 129 | ** ''The Kennett Paper'' {{WS|kennettpaper.com}} of [[Kennett Square, Pennsylvania]] 130 | ** ''Avon Grove Sun'' {{WS|avongrovesun.com}} of [[West Grove, Pennsylvania]] 131 | ** ''The Central Record'' {{WS|medfordcentralrecord.com}} of [[Medford, New Jersey]] 132 | ** ''Maple Shade Progress'' {{WS|mapleshadeprogress.com}} of [[Maple Shade, New Jersey]] 133 | 134 | * Intercounty Newspapers {{WS|buckslocalnews.com}} {{WS|southjerseylocalnews.com}} 135 | ** ''The Pennington Post'' {{WS|penningtonpost.com}} of [[Pennington, New Jersey]] 136 | ** ''The Bristol Pilot'' {{WS|bristolpilot.com}} of [[Bristol, Pennsylvania]] 137 | ** ''Yardley News'' {{WS|yardleynews.com}} of [[Yardley, Pennsylvania]] 138 | ** ''Advance of Bucks County'' {{WS|advanceofbucks.com}} of [[Newtown, Pennsylvania]] 139 | ** ''Record Breeze'' {{WS|recordbreeze.com}} of [[Berlin, New Jersey]] 140 | ** ''Community News'' {{WS|sjcommunitynews.com}} of [[Pemberton, New Jersey]] 141 | 142 | * Montgomery Newspapers {{WS|montgomerynews.com}} 143 | ** ''Ambler Gazette'' {{WS|amblergazette.com}} of [[Ambler, Pennsylvania]] 144 | ** ''The Colonial'' {{WS|colonialnews.com}} of [[Plymouth Meeting, Pennsylvania]] 145 | ** ''Glenside News'' {{WS|glensidenews.com}} of [[Glenside, Pennsylvania]] 146 | ** ''The Globe'' {{WS|globenewspaper.com}} of [[Lower Moreland Township, Pennsylvania]] 147 | ** ''Montgomery Life'' {{WS|montgomerylife.com}} of [[Fort Washington, Pennsylvania]] 148 | ** ''North Penn Life'' {{WS|northpennlife.com}} of [[Lansdale, Pennsylvania]] 149 | ** ''Perkasie News Herald'' {{WS|perkasienewsherald.com}} of [[Perkasie, Pennsylvania]] 150 | ** ''Public Spirit'' {{WS|thepublicspirit.com}} of [[Hatboro, Pennsylvania]] 151 | ** ''Souderton Independent'' {{WS|soudertonindependent.com}} of [[Souderton, Pennsylvania]] 152 | ** ''Springfield Sun'' {{WS|springfieldsun.com}} of [[Springfield, Pennsylvania]] 153 | ** ''Spring-Ford Reporter'' {{WS|springfordreporter.com}} of [[Royersford, Pennsylvania]] 154 | ** ''Times Chronicle'' {{WS|thetimeschronicle.com}} of [[Jenkintown, Pennsylvania]] 155 | ** ''Valley Item'' {{WS|valleyitem.com}} of [[Perkiomenville, Pennsylvania]] 156 | ** ''Willow Grove Guide'' {{WS|willowgroveguide.com}} of [[Willow Grove, Pennsylvania]] 157 | ** ''The Review'' {{WS|roxreview.com}} of [[Roxborough, Philadelphia, Pennsylvania]] 158 | 159 | * Main Line Media News {{WS|mainlinemedianews.com}} 160 | ** ''Main Line Times'' {{WS|mainlinetimes.com}} of [[Ardmore, Pennsylvania]] 161 | ** ''Main Line Life'' {{WS|mainlinelife.com}} of [[Ardmore, Pennsylvania]] 162 | ** ''The King of Prussia Courier'' {{WS|kingofprussiacourier.com}} of [[King of Prussia, Pennsylvania]] 163 | 164 | * Delaware County News Network {{WS|delconewsnetwork.com}} 165 | ** ''News of Delaware County'' {{WS|newsofdelawarecounty.com}} of [[Havertown, Pennsylvania]] 166 | ** ''County Press'' {{WS|countypressonline.com}} of [[Newtown Square, Pennsylvania]] 167 | ** ''Garnet Valley Press'' {{WS|countypressonline.com}} of [[Glen Mills, Pennsylvania]] 168 | ** ''Springfield Press'' {{WS|countypressonline.com}} of [[Springfield, Pennsylvania]] 169 | ** ''Town Talk'' {{WS|towntalknews.com}} of [[Ridley, Pennsylvania]] 170 | 171 | * Berks-Mont Newspapers {{WS|berksmontnews.com}} 172 | ** ''The Boyertown Area Times'' {{WS|berksmontnews.com/boyertown_area_times}} of [[Boyertown, Pennsylvania]] 173 | ** ''The Kutztown Area Patriot'' {{WS|berksmontnews.com/kutztown_area_patriot}} of [[Kutztown, Pennsylvania]] 174 | ** ''The Hamburg Area Item'' {{WS|berksmontnews.com/hamburg_area_item}} of [[Hamburg, Pennsylvania]] 175 | ** ''The Southern Berks News'' {{WS|berksmontnews.com/southern_berks_news}} of [[Exeter Township, Berks County, Pennsylvania]] 176 | ** ''Community Connection'' {{WS|berksmontnews.com/community_connection}} of [[Boyertown, Pennsylvania]] 177 | 178 | * Magazines 179 | ** ''Bucks Co. Town & Country Living'' {{WS|buckscountymagazine.com}} 180 | ** ''Parents Express'' {{WS|parents-express.com}} 181 | ** ''Real Men, Rednecks'' {{WS|realmenredneck.com}} 182 | 183 | {{JRC}} 184 | 185 | ==References== 186 | 187 | 188 | [[Category:Journal Register publications|*]] 189 | -------------------------------------------------------------------------------- /Tests/DiffMatchPatchTest-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/DiffMatchPatchTest.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import 24 | 25 | 26 | @interface DiffMatchPatchTest : XCTestCase { 27 | 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Tests/TestUtilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2011 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: jan@geheimwerk.de (Jan Weiß) 20 | */ 21 | 22 | 23 | #import 24 | 25 | NSString * diff_stringForFilePath(NSString *aFilePath); 26 | NSString * diff_stringForURL(NSURL *aURL); 27 | -------------------------------------------------------------------------------- /Tests/TestUtilities.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2011 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: jan@geheimwerk.de (Jan Weiß) 20 | */ 21 | 22 | #import "TestUtilities.h" 23 | #import "JXArcCompatibilityMacros.h" 24 | 25 | NSString * diff_stringForFilePath(NSString *aFilePath) { 26 | NSString *absoluteFilePath; 27 | 28 | // FIXME: This does not work correctly with aliases: the alias file itself is read. 29 | // We can use the code from here to fix this: 30 | // http://cocoawithlove.com/2010/02/resolving-path-containing-mixture-of.html 31 | if ([aFilePath isAbsolutePath]) { 32 | absoluteFilePath = aFilePath; 33 | } 34 | else { 35 | absoluteFilePath = [[NSString pathWithComponents: 36 | [NSArray arrayWithObjects: 37 | [[NSFileManager defaultManager] currentDirectoryPath], 38 | aFilePath, 39 | nil] 40 | ] stringByStandardizingPath]; 41 | } 42 | 43 | NSURL *aURL = [NSURL fileURLWithPath:absoluteFilePath]; 44 | 45 | return diff_stringForURL(aURL); 46 | } 47 | 48 | NSString * diff_stringForURL(NSURL *aURL) { 49 | NSDictionary *documentOptions = [NSDictionary dictionary]; 50 | NSDictionary *documentAttributes; 51 | NSError *error; 52 | NSAttributedString *attributedString = [[NSAttributedString alloc] 53 | initWithURL:aURL 54 | options:documentOptions 55 | documentAttributes:&documentAttributes error:&error]; 56 | if (!attributedString) { 57 | NSLog(@"%@", error); 58 | } 59 | 60 | // For performance reasons, NSAttributedString’s -string method returns the current backing store of the attributed string object. 61 | // We need to make a copy or we will get a zombie soon after releasing attributedString below. 62 | NSString *string = JX_AUTORELEASE([[attributedString string] copy]); 63 | 64 | JX_RELEASE(attributedString); 65 | 66 | return string; 67 | } 68 | -------------------------------------------------------------------------------- /Tests/mode-test.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2011 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import 24 | 25 | #import 26 | #import "TestUtilities.h" 27 | #import "JXArcCompatibilityMacros.h" 28 | 29 | 30 | typedef enum { 31 | DiffDefaultMode = 1, 32 | DiffLineMode = 2, 33 | DiffWordMode = 3, 34 | DiffParagraphMode = 4, 35 | DiffSentenceMode = 5, 36 | DiffLineBreakDelimiteredMode = 6 37 | } DiffMode; 38 | 39 | 40 | NSMutableArray * diff_defaultMode(NSString *text1, NSString *text2); 41 | NSMutableArray * diff_withMode(NSString *text1, NSString *text2, DiffMode mode); 42 | 43 | NSMutableArray * diff_withMode(NSString *text1, NSString *text2, DiffMode mode) { 44 | DiffMatchPatch *dmp = [DiffMatchPatch new]; 45 | 46 | DiffTokenMode tokenMode = 0; 47 | 48 | switch (mode) { 49 | case DiffDefaultMode: 50 | tokenMode = 0; 51 | break; 52 | case DiffLineMode: 53 | tokenMode = -1; 54 | break; 55 | case DiffWordMode: 56 | tokenMode = DiffWordTokens; 57 | break; 58 | case DiffParagraphMode: 59 | tokenMode = DiffParagraphTokens; 60 | break; 61 | case DiffSentenceMode: 62 | tokenMode = DiffSentenceTokens; 63 | break; 64 | case DiffLineBreakDelimiteredMode: 65 | tokenMode = DiffLineBreakDelimiteredTokens; 66 | break; 67 | default: 68 | tokenMode = 0; 69 | break; 70 | } 71 | 72 | NSMutableArray *tokenArray; 73 | if (tokenMode != 0) { 74 | NSArray *a; 75 | if (mode == DiffLineMode) { 76 | a = [dmp diff_linesToCharsForFirstString:text1 andSecondString:text2]; 77 | } 78 | else { 79 | a = [dmp diff_tokensToCharsForFirstString:text1 andSecondString:text2 mode:tokenMode]; 80 | } 81 | 82 | NSString *tokenText1 = [a objectAtIndex:0]; 83 | NSString *tokenText2 = [a objectAtIndex:1]; 84 | tokenArray = [a objectAtIndex:2]; 85 | 86 | text1 = tokenText1; 87 | text2 = tokenText2; 88 | } 89 | 90 | dmp.Diff_Timeout = 0; 91 | NSMutableArray *diffs = [dmp diff_mainOfOldString:text1 andNewString:text2 checkLines:NO]; 92 | 93 | if (tokenMode != 0) { 94 | [dmp diff_chars:diffs toLines:tokenArray]; 95 | } 96 | 97 | JX_RELEASE(dmp); 98 | 99 | return diffs; 100 | } 101 | 102 | NSMutableArray * diff_defaultMode(NSString *text1, NSString *text2) { 103 | DiffMatchPatch *dmp = JX_AUTORELEASE([DiffMatchPatch new]); 104 | 105 | dmp.Diff_Timeout = 0; 106 | NSMutableArray *diffs = [dmp diff_mainOfOldString:text1 andNewString:text2 checkLines:NO]; 107 | 108 | return diffs; 109 | } 110 | 111 | 112 | int main (int argc, const char * argv[]) { 113 | JX_NEW_AUTORELEASE_POOL_WITH_NAME(pool) 114 | 115 | NSArray *cliArguments = [[NSProcessInfo processInfo] arguments]; 116 | 117 | if ([cliArguments count] < 3) { 118 | fprintf(stderr, "usage: %s [default|line|word|paragraph|sentence|line-break-delimitered]\n", 119 | [[[NSProcessInfo processInfo] processName] UTF8String]); 120 | JX_DRAIN_AUTORELEASE_POOL_WITH_NAME(pool); 121 | return EXIT_FAILURE; 122 | } 123 | 124 | NSString *text1 = diff_stringForFilePath([cliArguments objectAtIndex:1]); 125 | NSString *text2 = diff_stringForFilePath([cliArguments objectAtIndex:2]); 126 | 127 | if (text1 == nil || text2 == nil) { 128 | return EXIT_FAILURE; 129 | } 130 | 131 | NSMutableArray *diffs; 132 | DiffMode mode = DiffDefaultMode; 133 | 134 | if ([cliArguments count] >= 4) { 135 | NSString *modeString = [cliArguments objectAtIndex:3]; 136 | 137 | if ([modeString isEqualToString:@"line"]) { 138 | mode = DiffLineMode; 139 | } 140 | else if ([modeString isEqualToString:@"word"]) { 141 | mode = DiffWordMode; 142 | } 143 | else if ([modeString isEqualToString:@"paragraph"]) { 144 | mode = DiffParagraphMode; 145 | } 146 | else if ([modeString isEqualToString:@"sentence"]) { 147 | mode = DiffSentenceMode; 148 | } 149 | else if ([modeString isEqualToString:@"line-break-delimitered"]) { 150 | mode = DiffLineBreakDelimiteredMode; 151 | } 152 | } 153 | 154 | diffs = diff_withMode(text1, text2, mode); 155 | 156 | NSLog(@"%@", [diffs description]); 157 | 158 | JX_END_AUTORELEASE_POOL_WITH_NAME(pool) 159 | 160 | return EXIT_SUCCESS; 161 | } 162 | -------------------------------------------------------------------------------- /Tests/speedtest.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Diff Match and Patch 3 | * 4 | * Copyright 2010 geheimwerk.de. 5 | * http://code.google.com/p/google-diff-match-patch/ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | * Author: fraser@google.com (Neil Fraser) 20 | * ObjC port: jan@geheimwerk.de (Jan Weiß) 21 | */ 22 | 23 | #import 24 | 25 | #import 26 | #import "TestUtilities.h" 27 | #import "JXArcCompatibilityMacros.h" 28 | 29 | void diff_measureTimeForDiff(DiffMatchPatch *dmp, NSString *text1, NSString *text2, NSString *aDescription); 30 | 31 | void diff_measureTimeForDiff(DiffMatchPatch *dmp, NSString *text1, NSString *text2, NSString *aDescription) { 32 | NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; 33 | [dmp diff_mainOfOldString:text1 andNewString:text2]; 34 | NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - start; 35 | 36 | NSLog(@"%@Elapsed time: %.4lf", aDescription, (double)duration); 37 | } 38 | 39 | int main (int argc, const char * argv[]) { 40 | JX_NEW_AUTORELEASE_POOL_WITH_NAME(pool) 41 | 42 | NSString *text1FilePath = @"Speedtest1.txt"; 43 | NSString *text2FilePath = @"Speedtest2.txt"; 44 | 45 | NSArray *cliArguments = [[NSProcessInfo processInfo] arguments]; 46 | 47 | if ([cliArguments count] == 3) { 48 | text1FilePath = [cliArguments objectAtIndex:1]; 49 | text2FilePath = [cliArguments objectAtIndex:2]; 50 | } 51 | 52 | NSString *text1 = diff_stringForFilePath(text1FilePath); 53 | NSString *text2 = diff_stringForFilePath(text2FilePath); 54 | 55 | DiffMatchPatch *dmp = [DiffMatchPatch new]; 56 | dmp.Diff_Timeout = 0; 57 | 58 | NSString *aDescription; 59 | 60 | #ifdef ENABLE_PERFORMANCE_TABLE_OUTPUT 61 | NSUInteger limit; 62 | for (int i = 8; i <= 24; i++) { 63 | limit = pow(2.0, i); 64 | if (limit > text1.length || limit > text2.length) break; 65 | 66 | aDescription = [NSString stringWithFormat:@"%8lu unichars, ", (unsigned long)limit]; 67 | diff_measureTimeForDiff(dmp, [text1 substringToIndex:limit], [text2 substringToIndex:limit], aDescription); 68 | } 69 | #endif 70 | 71 | aDescription = [NSString stringWithFormat:@"%8lu unichars, ", (unsigned long)MAX(text1.length, text2.length)]; 72 | diff_measureTimeForDiff(dmp, text1, text2, aDescription); 73 | 74 | JX_RELEASE(dmp); 75 | 76 | JX_END_AUTORELEASE_POOL_WITH_NAME(pool) 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /speedtest_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'speedtest' target in the 'DiffMatchPatch' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | --------------------------------------------------------------------------------