Revision: 13820
          http://sourceforge.net/p/skim-app/code/13820
Author:   hofman
Date:     2023-12-03 10:34:00 +0000 (Sun, 03 Dec 2023)
Log Message:
-----------
Enable ARC in all SkimNotes targets. Use static type for class factory methods, 
classes shouldn't be subclassed. Declare @proprties instead of accessors.

Modified Paths:
--------------
    trunk/SkimNotes/Configurations/SkimNotes-App.xcconfig
    trunk/SkimNotes/Configurations/SkimNotes-Common.xcconfig
    trunk/SkimNotes/PDFAnnotation_SKNExtensions.h
    trunk/SkimNotes/PDFAnnotation_SKNExtensions.m
    trunk/SkimNotes/PDFDocument_SKNExtensions.m
    trunk/SkimNotes/SKNAgentListener.h
    trunk/SkimNotes/SKNAgentListener.m
    trunk/SkimNotes/SKNDocument.h
    trunk/SkimNotes/SKNDocument.m
    trunk/SkimNotes/SKNExtendedAttributeManager.h
    trunk/SkimNotes/SKNExtendedAttributeManager.m
    trunk/SkimNotes/SKNPDFAnnotationNote.h
    trunk/SkimNotes/SKNPDFAnnotationNote.m
    trunk/SkimNotes/SKNSkimReader.h
    trunk/SkimNotes/SKNSkimReader.m
    trunk/SkimNotes/SKNUtilities.m
    trunk/SkimNotes/SKNXPCSkimReader.h
    trunk/SkimNotes/SKNXPCSkimReader.m
    trunk/SkimNotes/skimnotes.m
    trunk/SkimNotes/skimpdf.m

Modified: trunk/SkimNotes/Configurations/SkimNotes-App.xcconfig
===================================================================
--- trunk/SkimNotes/Configurations/SkimNotes-App.xcconfig       2023-12-01 
10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/Configurations/SkimNotes-App.xcconfig       2023-12-03 
10:34:00 UTC (rev 13820)
@@ -10,5 +10,3 @@
 
 GCC_PRECOMPILE_PREFIX_HEADER = YES
 GCC_PREFIX_HEADER = 
$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h
-
-CLANG_ENABLE_OBJC_ARC = YES

Modified: trunk/SkimNotes/Configurations/SkimNotes-Common.xcconfig
===================================================================
--- trunk/SkimNotes/Configurations/SkimNotes-Common.xcconfig    2023-12-01 
10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/Configurations/SkimNotes-Common.xcconfig    2023-12-03 
10:34:00 UTC (rev 13820)
@@ -21,6 +21,8 @@
 // GC is not supported in Xcode 5, and we never need it
 //GCC_ENABLE_OBJC_GC = supported
 
+CLANG_ENABLE_OBJC_ARC = YES
+
 ENABLE_STRICT_OBJC_MSGSEND = YES
 
 GCC_C_LANGUAGE_STANDARD = c99

Modified: trunk/SkimNotes/PDFAnnotation_SKNExtensions.h
===================================================================
--- trunk/SkimNotes/PDFAnnotation_SKNExtensions.h       2023-12-01 10:13:51 UTC 
(rev 13819)
+++ trunk/SkimNotes/PDFAnnotation_SKNExtensions.h       2023-12-03 10:34:00 UTC 
(rev 13820)
@@ -290,37 +290,23 @@
     @discussion These properties can be used to initialize a new copy, and to 
save to extended attributes or file.
     @result     A dictionary with properties of the Skim note.  All values are 
standard Cocoa objects conforming to <code>NSCoding</code> and 
<code>NSCopying</code>.
 */
-- (NSDictionary *)SkimNoteProperties;
+@property (nonatomic, readonly) NSDictionary *SkimNoteProperties;
 
 /*!
     @abstract   Returns whether the annotation is a Skim note.  
-    @discussion An annotation initalized with initializers starting with 
initSkimNote will return <code>YES</code> by default.
+    @discussion An annotation initalized with initializers starting with 
initSkimNote will return <code>YES</code> by default.  You normally would not 
set this yourself, but rely on the initializer to set the 
<code>isSkimNote</code> flag.
     @result     YES if the annotation is a Skim note; otherwise NO.
 */
-- (BOOL)isSkimNote;
+@property (nonatomic, getter=isSkimNote) BOOL SkimNote;
 
 /*!
-    @abstract   Sets whether the receiver is to be interpreted as a Skim note.
-    @discussion You normally would not use this yourself, but rely on the 
initializer to set the <code>isSkimNote</code> flag.
-    @param      flag Set this value to <code>YES</code> if you want the 
annotation to be interpreted as a Skim note.
-*/
-- (void)setSkimNote:(BOOL)flag;
-
-/*!
     @abstract   The string value of the annotation.
-    @discussion By default, this is just the same as the contents.  However 
for <code>SKNPDFAnnotationNote</code> the contents will contain both string and 
text.
+    @discussion By default, this is just the same as the contents.  However 
for <code>SKNPDFAnnotationNote</code> the contents will contain both string and 
text.  Normally you set this by setting the <code>content</code> property.
     @result     A string representing the string value associated with the 
annotation.
 */
-- (NSString *)string;
+@property (nonatomic, retain) NSString *string;
 
 /*!
-    @abstract   Sets the string of the annotation.  By default just sets the 
contents.
-    @discussion By default just calls <code>setContent:</code>.
-    @param      newString The new string value for the annotation.
-*/
-- (void)setString:(NSString *)newString;
-
-/*!
     @abstract   Method to get the points from a path of an Ink Skim note.
     @param      path The bezier path for which to get the points.
     @discussion This method gets the points between which the path 
interpolates.

Modified: trunk/SkimNotes/PDFAnnotation_SKNExtensions.m
===================================================================
--- trunk/SkimNotes/PDFAnnotation_SKNExtensions.m       2023-12-01 10:13:51 UTC 
(rev 13819)
+++ trunk/SkimNotes/PDFAnnotation_SKNExtensions.m       2023-12-03 10:34:00 UTC 
(rev 13820)
@@ -151,11 +151,6 @@
 #if defined(PDFKIT_PLATFORM_IOS)
         return [UIColor colorWithWhite:c[0] alpha:c[1]];
 #else
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
-        if ([NSColorSpace 
respondsToSelector:@selector(genericGamma22GrayColorSpace)] == NO)
-            return [NSColor colorWithColorSpace:[NSColorSpace 
genericGrayColorSpace] components:c count:2];
-        else
-#endif
         return [NSColor colorWithColorSpace:[NSColorSpace 
genericGamma22GrayColorSpace] components:c count:2];
 #endif
     } else {
@@ -205,32 +200,8 @@
 
 @implementation PDFAnnotation (SKNExtensions)
 
-#if !defined(PDFKIT_PLATFORM_IOS) && MAC_OS_X_VERSION_MIN_REQUIRED < 
MAC_OS_X_VERSION_10_6
-
-static NSHashTable *SkimNotes = nil;
-
-static void (*original_dealloc)(id, SEL) = NULL;
-
-static void replacement_dealloc(id self, SEL _cmd) {
-    @synchronized([PDFAnnotation self]) {
-        [SkimNotes removeObject:self];
-    }
-    original_dealloc(self, _cmd);
-}
-
-+ (void)load {
-    NSAutoreleasePool *pool = [NSAutoreleasePool new];
-    SkimNotes = [[NSHashTable alloc] 
initWithOptions:NSHashTableZeroingWeakMemory | 
NSHashTableObjectPointerPersonality capacity:0];
-    original_dealloc = 
(void(*)(id,SEL))method_setImplementation(class_getInstanceMethod(self, 
@selector(dealloc)), (IMP)replacement_dealloc);
-    [pool release];
-}
-
-#else
-
 char SKNIsSkimNoteKey;
 
-#endif
-
 #if !defined(PDFKIT_PLATFORM_IOS)
 static inline Class SKNAnnotationClassForType(NSString *type) {
 #pragma clang diagnostic push
@@ -266,7 +237,7 @@
     if ([type isEqualToString:SKNNoteString] || [type 
isEqualToString:SKNTextString]) {
         if ([self isMemberOfClass:[PDFAnnotation class]]) {
             // replace by our subclass
-            [[self init] release];
+            [self init];
             self = [[SKNPDFAnnotationNote alloc] initSkimNoteWithBounds:bounds 
forType:type];
             return self;
         } else if ([self isKindOfClass:[SKNPDFAnnotationNote class]]) {
@@ -291,7 +262,7 @@
         
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-        [[self initWithBounds:NSZeroRect] release];
+        self = [self initWithBounds:NSZeroRect];
 #pragma clang diagnostic pop
         self = [annotationClass alloc];
     }
@@ -349,7 +320,7 @@
     
     if (([type isEqualToString:SKNNoteString] || [type 
isEqualToString:SKNTextString]) && [self isMemberOfClass:[PDFAnnotation 
class]]) {
         // replace by our subclass
-        [[self init] release];
+        [self init];
         self = [[SKNPDFAnnotationNote alloc] initSkimNoteWithProperties:dict];
         return self;
     }
@@ -362,7 +333,7 @@
         
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-        [[self initWithBounds:NSZeroRect] release];
+        self = [self initWithBounds:NSZeroRect];
 #pragma clang diagnostic pop
         self = [[annotationClass alloc] initSkimNoteWithProperties:dict];
         return self;
@@ -399,7 +370,7 @@
             if ([borderStyle respondsToSelector:@selector(integerValue)] == NO)
                 borderStyle = nil;
             if ([self border] == nil)
-                [self setBorder:[[[PDFBorder alloc] init] autorelease]];
+                [self setBorder:[[PDFBorder alloc] init]];
             if ([lineWidth respondsToSelector:@selector(doubleValue)])
                 [[self border] setLineWidth:[lineWidth doubleValue]];
             if ([dashPattern isKindOfClass:arrayClass])
@@ -468,10 +439,8 @@
                 PDFPoint p = SKNPointFromString([pointStrings 
objectAtIndex:i]);
                 NSValue *val = [[NSValue alloc] initWithBytes:&p 
objCType:@encode(PDFPoint)];
                 [pointValues addObject:val];
-                [val release];
             }
             [self setQuadrilateralPoints:pointValues];
-            [pointValues release];
         }
         
         if ([type isEqualToString:SKNTextString] || [type 
isEqualToString:SKNNoteString]) {
@@ -490,7 +459,6 @@
                         PDFKitPlatformBezierPath *path = 
[[PDFKitPlatformBezierPath alloc] init];
                         [[self class] setPoints:pointStrings 
ofSkimNotePath:path];
                         [self addBezierPath:path];
-                        [path release];
                     }
                 }
             }
@@ -684,7 +652,6 @@
                     for (i = 0; i < iMax; i++)
                         [quadPointStrings 
addObject:SKNStringFromPoint(SKNPointFromValue([quadPoints objectAtIndex:i]))];
                     [dict setValue:quadPointStrings 
forKey:SKNPDFAnnotationQuadrilateralPointsKey];
-                    [quadPointStrings release];
                 }
             } else if ((value = [self valueForAnnotationKey:@"/QuadPoints"])) {
                 if ([value isKindOfClass:arrayClass] && [value count] % 4 == 
0) {
@@ -724,7 +691,6 @@
                             [pointLists addObject:pointStrings];
                     }
                     [dict setValue:pointLists 
forKey:SKNPDFAnnotationPointListsKey];
-                    [pointLists release];
                 }
            } else if ((value = [self valueForAnnotationKey:@"/InkList"])) {
                 if ([value isKindOfClass:arrayClass]) {
@@ -789,7 +755,6 @@
                         }
                     }
                 }
-                [scanner release];
             }
             if (font)
                 [dict setObject:font forKey:SKNPDFAnnotationFontKey];
@@ -811,7 +776,6 @@
                         while ([scanner scanDouble:&c])
                             [array addObject:[NSNumber numberWithDouble:c]];
                         fontColor = SKNColorFromArray(array);
-                        [scanner release];
                     }
                 }
             }
@@ -859,26 +823,11 @@
 }
 
 - (BOOL)isSkimNote {
-#if !defined(PDFKIT_PLATFORM_IOS) && MAC_OS_X_VERSION_MIN_REQUIRED < 
MAC_OS_X_VERSION_10_6
-    BOOL isSkimNote;
-    @synchronized([PDFAnnotation self]) {
-        isSkimNote = [SkimNotes containsObject:self];
-    }
-    return isSkimNote;
-#else
     return [objc_getAssociatedObject(self, &SKNIsSkimNoteKey) boolValue];
-#endif
 }
 
 - (void)setSkimNote:(BOOL)flag {
-#if !defined(PDFKIT_PLATFORM_IOS) && MAC_OS_X_VERSION_MIN_REQUIRED < 
MAC_OS_X_VERSION_10_6
-    @synchronized([PDFAnnotation self]) {
-        if (flag) [SkimNotes addObject:self];
-        else [SkimNotes removeObject:self];
-    }
-#else
     objc_setAssociatedObject(self, &SKNIsSkimNoteKey, flag ? [NSNumber 
numberWithBool:YES] : nil, OBJC_ASSOCIATION_RETAIN);
-#endif
 }
 
 - (NSString *)string {
@@ -906,8 +855,8 @@
     return [self contents];
 }
 
-- (void)setString:(NSString *)newString {
-    [self setContents:newString];
+- (void)setString:(NSString *)string {
+    [self setContents:string];
 }
 
 + (NSArray *)pointsFromSkimNotePath:(PDFKitPlatformBezierPath *)path {
@@ -1258,11 +1207,9 @@
                 for (j = 0; j < 4; j++) {
                     NSValue *value = [[NSValue alloc] initWithBytes:&p[j] 
objCType:@encode(NSPoint)];
                     [quadPoints addObject:value];
-                    [value release];
                 }
             }
             [self setQuadrilateralPoints:quadPoints];
-            [quadPoints release];
         }
         
     }
@@ -1278,7 +1225,6 @@
         for (i = 0; i < iMax; i++)
             [quadPointStrings addObject:NSStringFromPoint([[quadPoints 
objectAtIndex:i] pointValue])];
         [dict setValue:quadPointStrings 
forKey:SKNPDFAnnotationQuadrilateralPointsKey];
-        [quadPointStrings release];
     }
     return dict;
 }
@@ -1325,7 +1271,6 @@
                     NSBezierPath *path = [[NSBezierPath alloc] init];
                     [selfClass setPoints:pointStrings ofSkimNotePath:path];
                     [self addBezierPath:path];
-                    [path release];
                 }
             }
         }
@@ -1347,7 +1292,6 @@
                 [pointLists addObject:pointStrings];
         }
         [dict setValue:pointLists forKey:SKNPDFAnnotationPointListsKey];
-        [pointLists release];
     }
     return dict;
 }
@@ -1388,8 +1332,8 @@
     return [self stringValue];
 }
 
-- (void)setString:(NSString *)newString {
-    [self setStringValue:newString];
+- (void)setString:(NSString *)string {
+    [self setStringValue:string];
 }
 
 @end
@@ -1427,8 +1371,8 @@
     return [NSString stringWithFormat:@"%ld", (long)[self state]];
 }
 
-- (void)setString:(NSString *)newString {
-    [self setState:[newString integerValue]];
+- (void)setString:(NSString *)string {
+    [self setState:[string integerValue]];
 }
 
 @end
@@ -1467,55 +1411,10 @@
     return [self stringValue];
 }
 
-- (void)setString:(NSString *)newString {
-    [self setStringValue:newString];
+- (void)setString:(NSString *)string {
+    [self setStringValue:string];
 }
 
 @end
 
-#pragma mark -
-
-#if __LP64__ && MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
-
-// the implementation of -[PDFBorder dashPattern] is badly broken on 10.4 and 
10.5 in the 64-bit binary, probably due to the wrong type for 
_pdfPriv.dashCount or _pdfPriv.dashPattern
-
-@implementation PDFBorder (SKNExtensions)
-
-static NSArray *replacement_dashPattern(id self, SEL _cmd) {
-    NSMutableArray *pattern = [NSMutableArray array];
-    @try {
-        id vars = nil;
-        if (NULL != object_getInstanceVariable(vars, "_pdfPriv", (void 
**)&vars)) {
-            Ivar countIvar = object_getInstanceVariable(vars, "dashCount", 
NULL);
-            if (countIvar != NULL) {
-                NSUInteger i, count = *(unsigned int *)((void *)vars + 
ivar_getOffset(countIvar));
-                Ivar patternIvar = object_getInstanceVariable(vars, 
"dashPattern", NULL);
-                if (patternIvar != NULL) {
-                    float *dashPattern = *(float **)((void *)vars + 
ivar_getOffset(patternIvar));
-                    for (i = 0; i < count; i++)
-                        [pattern addObject:[NSNumber 
numberWithDouble:dashPattern[i]]];
-                }
-            }
-        }
-    }
-    @catch (id e) {}
-    return pattern;
-}
-
-+ (void)load {
-    if (class_getInstanceVariable(self, "_pdfPriv")) {
-        Class cls = NSClassFromString(@"PDFBorderPrivateVars");
-        if (cls) {
-            Ivar dashCountIvar = class_getInstanceVariable(cls, "dashCount");
-            Ivar dashPatternIvar = class_getInstanceVariable(cls, 
"dashPattern");
-            if (dashCountIvar && 0 == 
strcmp(ivar_getTypeEncoding(dashCountIvar), @encode(unsigned int)) && 
dashPatternIvar && 0 == strcmp(ivar_getTypeEncoding(dashPatternIvar), 
@encode(float *)))
-                class_replaceMethod(self, @selector(dashPattern), 
(IMP)replacement_dashPattern, "@@:");
-        }
-    }
-}
-
-@end
-
 #endif
-
-#endif

Modified: trunk/SkimNotes/PDFDocument_SKNExtensions.m
===================================================================
--- trunk/SkimNotes/PDFDocument_SKNExtensions.m 2023-12-01 10:13:51 UTC (rev 
13819)
+++ trunk/SkimNotes/PDFDocument_SKNExtensions.m 2023-12-03 10:34:00 UTC (rev 
13820)
@@ -139,7 +139,7 @@
     if ([self pageCount] == 0) return nil;
     
     // create new annotations from the dictionary and add them to their page 
and to the document
-    while (NSDictionary *dict in noteDicts) {
+    for (NSDictionary *dict in noteDicts) {
         NSUInteger pageIndex = [[dict 
objectForKey:SKNPDFAnnotationPageIndexKey] unsignedIntegerValue];
         if ([[dict objectForKey:SKNPDFAnnotationTypeKey] 
isEqualToString:SKNWidgetString]) {
             if (pageIndex >= [self pageCount])
@@ -179,7 +179,6 @@
             PDFPage *page = [self pageAtIndex:pageIndex];
             [page addAnnotation:annotation];
             [notes addObject:annotation];
-            [annotation release];
         }
     }
     

Modified: trunk/SkimNotes/SKNAgentListener.h
===================================================================
--- trunk/SkimNotes/SKNAgentListener.h  2023-12-01 10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/SKNAgentListener.h  2023-12-03 10:34:00 UTC (rev 13820)
@@ -42,11 +42,11 @@
 {
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-    NSConnection *connection;
+    NSConnection *_connection;
 #pragma clang diagnostic pop
 #if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MAX_ALLOWED >= 
MAC_OS_X_VERSION_10_8
-    NSXPCListener *xpcListener;
-    NSXPCConnection *xpcConnection;
+    NSXPCListener *_xpcListener;
+    NSXPCConnection *_xpcConnection;
 #endif
 }
 

Modified: trunk/SkimNotes/SKNAgentListener.m
===================================================================
--- trunk/SkimNotes/SKNAgentListener.m  2023-12-01 10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/SKNAgentListener.m  2023-12-03 10:34:00 UTC (rev 13820)
@@ -92,7 +92,6 @@
             [fh writeData:[serverName dataUsingEncoding:NSUTF8StringEncoding]];
             [fh closeFile];
         } else {
-            [self release];
             self = nil;
         }
     }
@@ -100,12 +99,10 @@
 }
 
 - (void)dealloc {
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
     [self destroyConnection];
 #if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MAX_ALLOWED >= 
MAC_OS_X_VERSION_10_8
     [self destroyXPCConnection];
 #endif
-    [super dealloc];
 }
 
 @end
@@ -117,13 +114,13 @@
 - (BOOL)startConnectionWithServerName:(NSString *)serverName {
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-    connection = [[NSConnection alloc] initWithReceivePort:[NSPort port] 
sendPort:nil];
+    _connection = [[NSConnection alloc] initWithReceivePort:[NSPort port] 
sendPort:nil];
 #pragma clang diagnostic pop
     NSProtocolChecker *checker = [NSProtocolChecker 
protocolCheckerWithTarget:self protocol:@protocol(SKNAgentListenerProtocol)];
-    [connection setRootObject:checker];
-    [connection setDelegate:self];
+    [_connection setRootObject:checker];
+    [_connection setDelegate:self];
     
-    if ([connection registerName:serverName] == NO) {
+    if ([_connection registerName:serverName] == NO) {
         fprintf(stderr, "skimnotes agent pid %d: unable to register connection 
name %s; another process must be running\n", getpid(), [serverName UTF8String]);
         [self destroyConnection];
         return NO;
@@ -133,12 +130,11 @@
 }
 
 - (void)destroyConnection {
-    [connection registerName:nil];
-    [[connection receivePort] invalidate];
-    [[connection sendPort] invalidate];
-    [connection invalidate];
-    [connection release];
-    connection = nil;
+    [_connection registerName:nil];
+    [[_connection receivePort] invalidate];
+    [[_connection sendPort] invalidate];
+    [_connection invalidate];
+    _connection = nil;
 }
 
 - (void)portDied:(NSNotification *)notification {
@@ -192,26 +188,24 @@
 @implementation SKNAgentListener (SKNXPCConnection)
 
 - (BOOL)startXPCListenerWithServerName:(NSString *)serverName {
-    xpcListener = [[NSXPCListener alloc] initWithMachServiceName:serverName];
-    [xpcListener setDelegate:self];
-    [xpcListener resume];
+    _xpcListener = [[NSXPCListener alloc] initWithMachServiceName:serverName];
+    [_xpcListener setDelegate:self];
+    [_xpcListener resume];
     
     return YES;
 }
 
 - (void)destroyXPCConnection {
-    [xpcConnection invalidate];
-    [xpcConnection release];
-    xpcConnection = nil;
+    [_xpcConnection invalidate];
+    _xpcConnection = nil;
     
-    [xpcListener invalidate];
-    [xpcListener release];
-    xpcListener = nil;
+    [_xpcListener invalidate];
+    _xpcListener = nil;
 }
 
 // first app to connect will be the owner of this instance of the program; 
when the connection dies, so do we
 - (BOOL)listener:(NSXPCListener *)listener 
shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
-    if (xpcConnection) {
+    if (_xpcConnection) {
         [newConnection invalidate];
         return NO;
     }
@@ -218,14 +212,15 @@
     
     [newConnection setExportedInterface:[NSXPCInterface 
interfaceWithProtocol:@protocol(SKNXPCAgentListenerProtocol)]];
     [newConnection setExportedObject:self];
+    __weak SKNAgentListener *weakSelf = self;
     NSString *description = [newConnection description];
     [newConnection setInvalidationHandler:^{
-        [self destroyXPCConnection];
+        [weakSelf destroyXPCConnection];
         fprintf(stderr, "skimnotes agent pid %d dying because port %s is 
invalid\n", getpid(), [description UTF8String]);
         exit(0);
     }];
-    xpcConnection = [newConnection retain];
-    [xpcConnection resume];
+    _xpcConnection = newConnection;
+    [_xpcConnection resume];
     
     return YES;
 }

Modified: trunk/SkimNotes/SKNDocument.h
===================================================================
--- trunk/SkimNotes/SKNDocument.h       2023-12-01 10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/SKNDocument.h       2023-12-03 10:34:00 UTC (rev 13820)
@@ -48,7 +48,7 @@
 //#define ToolSample
 
 @interface SKNDocument : NSDocument {
-    NSArray *notes;
+    NSArray *_notes;
 }
 @property (nonatomic, copy) NSArray *notes;
 @end

Modified: trunk/SkimNotes/SKNDocument.m
===================================================================
--- trunk/SkimNotes/SKNDocument.m       2023-12-01 10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/SKNDocument.m       2023-12-03 10:34:00 UTC (rev 13820)
@@ -49,7 +49,7 @@
 
 @implementation SKNDocument
 
-@synthesize notes;
+@synthesize notes = _notes;
 
 + (void)initialize {
     [NSValueTransformer setValueTransformer:[[SKNPlusOneTransformer alloc] 
init] forName:@"SKNPlusOne"];
@@ -62,7 +62,7 @@
 - (instancetype)init {
     self = [super init];
     if (self) {
-        notes = [[NSArray alloc] init];
+        _notes = [[NSArray alloc] init];
     }
     return self;
 }
@@ -76,7 +76,7 @@
 #if defined(FrameworkSample)
     
     if ([[NSWorkspace sharedWorkspace] type:SKNSkimNotesDocumentType 
conformsToType:docType]) {
-        return [[NSFileManager defaultManager] writeSkimNotes:notes 
toSkimFileAtURL:absoluteURL error:outError];
+        return [[NSFileManager defaultManager] writeSkimNotes:_notes 
toSkimFileAtURL:absoluteURL error:outError];
     } else {
         if (outError)
             *outError = [NSError errorWithDomain:SKNDocumentErrorDomain code:0 
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Unable 
to save notes", @""), NSLocalizedDescriptionKey, nil]];
@@ -94,7 +94,7 @@
 - (NSData *)dataOfType:(NSString *)docType error:(NSError **)outError {
     NSData *data = nil;
     if ([[NSWorkspace sharedWorkspace] type:SKNSkimNotesDocumentType 
conformsToType:docType]) {
-        data = [NSKeyedArchiver archivedDataWithRootObject:notes];
+        data = [NSKeyedArchiver archivedDataWithRootObject:_notes];
     }
     if (data == nil && outError)
         *outError = [NSError errorWithDomain:SKNDocumentErrorDomain code:0 
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Unable 
to save notes", @""), NSLocalizedDescriptionKey, nil]];

Modified: trunk/SkimNotes/SKNExtendedAttributeManager.h
===================================================================
--- trunk/SkimNotes/SKNExtendedAttributeManager.h       2023-12-01 10:13:51 UTC 
(rev 13819)
+++ trunk/SkimNotes/SKNExtendedAttributeManager.h       2023-12-03 10:34:00 UTC 
(rev 13820)
@@ -91,18 +91,18 @@
     @discussion  This class is the core object to read and write extended 
attributes, which are used to store Skim notes with PDF files.
 */
 @interface SKNExtendedAttributeManager : NSObject {
-    NSString *namePrefix;
-    NSString *uniqueKey;
-    NSString *wrapperKey;
-    NSString *fragmentsKey;
+    NSString *_namePrefix;
+    NSString *_uniqueKey;
+    NSString *_wrapperKey;
+    NSString *_fragmentsKey;
 }
 
 /*!
-    @abstract   Returns the shared instance.  You probably always should use 
this instance, and is required for Skim notes.
+    @abstract   Returns the shared instance.  You should use always this 
instance for Skim notes.
     @discussion This shared manager uses the default prefix and is used for 
reading and writing Skim notes to PDF files.  It may split attributes into 
fragments if the data is too long.
     @result     The default shared EA manager used for Skim notes.
 */
-+ (id)sharedManager;
++ (SKNExtendedAttributeManager *)sharedManager;
 
 /*!
     @abstract   Returns a shared instance with nil prefix.  This instance 
never splits attributes, and can also not reassemble splitted attributes.
@@ -110,9 +110,16 @@
                 However attributes that were set using this manager will be 
readable also by managers with different prefixes, such as the 
<code>sharedManager</code>.
     @result     A shared EA manager that never splits extended attributes.
 */
-+ (id)sharedNoSplitManager;
++ (SKNExtendedAttributeManager *)sharedNoSplitManager;
 
 /*!
+    @abstract   Returns a shared instance appropriate for the containg 
application.  You may use this instance for attributes specific for the 
application.
+    @discussion This shared manager uses the identifier of the containg 
application as prefix.  It may split attributes into fragments if the data is 
too long.
+    @result     The default shared EA manager used for app specific attributes.
+*/
++ (SKNExtendedAttributeManager *)mainManager;
+
+/*!
     @abstract   Initializes a new extended attribute manager with keys and 
attribute name prefixes used for segments determined by a prefix.
     @discussion The prefix is used in splitting large attributes.  EA managers 
with different prefixes are mutually incompatible,
                 i.e. attributes written with one manager cannot be safely read 
by a manager with a different prefix.

Modified: trunk/SkimNotes/SKNExtendedAttributeManager.m
===================================================================
--- trunk/SkimNotes/SKNExtendedAttributeManager.m       2023-12-01 10:13:51 UTC 
(rev 13819)
+++ trunk/SkimNotes/SKNExtendedAttributeManager.m       2023-12-03 10:34:00 UTC 
(rev 13820)
@@ -72,29 +72,34 @@
 
 @implementation SKNExtendedAttributeManager
 
-static id sharedManager = nil;
-static id sharedNoSplitManager = nil;
++ (SKNExtendedAttributeManager *)sharedManager;
+{
+    static SKNExtendedAttributeManager *sharedManager = nil;
+    static dispatch_once_t onceToken = 0;
+    dispatch_once(&onceToken, ^{
+        sharedManager = [[self alloc] init];
+    });
+    return sharedManager;
+}
 
-+ (id)sharedManager;
++ (SKNExtendedAttributeManager *)sharedNoSplitManager;
 {
-    id manager;
-    @synchronized(self) {
-        if (sharedManager == nil)
-            sharedManager = [[[self class] alloc] init];
-        manager = sharedManager;
-    }
-    return manager;
+    static SKNExtendedAttributeManager *sharedNoSplitManager = nil;
+    static dispatch_once_t onceToken = 0;
+    dispatch_once(&onceToken, ^{
+        sharedNoSplitManager = [[self alloc] initWithPrefix:nil];
+    });
+    return sharedNoSplitManager;
 }
 
-+ (id)sharedNoSplitManager;
++ (SKNExtendedAttributeManager *)mainManager;
 {
-    id manager;
-    @synchronized(self) {
-        if (sharedNoSplitManager == nil)
-            sharedNoSplitManager = [[[self class] alloc] initWithPrefix:nil];
-        manager = sharedNoSplitManager;
-    }
-    return manager;
+    static SKNExtendedAttributeManager *mainManager = nil;
+    static dispatch_once_t onceToken = 0;
+    dispatch_once(&onceToken, ^{
+        mainManager = [[self alloc] initWithPrefix:[[NSBundle mainBundle] 
bundleIdentifier]];
+    });
+    return mainManager;
 }
 
 - (id)init;
@@ -106,22 +111,14 @@
 {
     self = [super init];
     if (self) {
-        namePrefix = [[prefix stringByAppendingString:NAME_SEPARATOR] retain];
-        uniqueKey = [[prefix stringByAppendingString:UNIQUE_KEY_SUFFIX] 
retain];
-        wrapperKey = [[prefix stringByAppendingString:WRAPPER_KEY_SUFFIX] 
retain];
-        fragmentsKey = [[prefix stringByAppendingString:FRAGMENTS_KEY_SUFFIX] 
retain];
+        _namePrefix = [prefix stringByAppendingString:NAME_SEPARATOR];
+        _uniqueKey = [prefix stringByAppendingString:UNIQUE_KEY_SUFFIX];
+        _wrapperKey = [prefix stringByAppendingString:WRAPPER_KEY_SUFFIX];
+        _fragmentsKey = [prefix stringByAppendingString:FRAGMENTS_KEY_SUFFIX];
     }
     return self;
 }
 
-- (void)dealloc {
-    [namePrefix release];
-    [uniqueKey release];
-    [wrapperKey release];
-    [fragmentsKey release];
-    [super dealloc];
-}
-
 - (NSArray *)extendedAttributeNamesAtPath:(NSString *)path 
traverseLink:(BOOL)follow includeFragments:(BOOL)fragments error:(NSError 
**)error;
 {
     const char *fsPath = [path fileSystemRepresentation];
@@ -144,15 +141,14 @@
         return nil;
     }
     
-    NSZone *zone = NSDefaultMallocZone();
     bufSize = status;
-    char *namebuf = (char *)NSZoneMalloc(zone, sizeof(char) * bufSize);
+    char *namebuf = (char *)malloc(sizeof(char) * bufSize);
     NSAssert(namebuf != NULL, @"unable to allocate memory");
     status = listxattr(fsPath, namebuf, bufSize, xopts);
     
     if(status == -1){
         if(error) *error = [self xattrError:errno forPath:path];
-        NSZoneFree(zone, namebuf);
+        free(namebuf);
         return nil;
     }
     
@@ -167,15 +163,14 @@
         attribute = [[NSString alloc] initWithBytes:&namebuf[start] 
length:(idx - start) encoding:NSUTF8StringEncoding];
         if(attribute != nil){
             // ignore fragments
-            if(fragments || namePrefix == nil || [attribute 
hasPrefix:namePrefix] == NO || [attribute length] < [namePrefix length] + 
MIN_EXTRA_NAME_LENGTH)
+            if(fragments || _namePrefix == nil || [attribute 
hasPrefix:_namePrefix] == NO || [attribute length] < [_namePrefix length] + 
MIN_EXTRA_NAME_LENGTH)
                 [attrs addObject:attribute];
-            [attribute release];
             attribute = nil;
         }
         start = idx + 1;
     }
     
-    NSZoneFree(zone, namebuf);
+    free(namebuf);
     return attrs;
 }
 
@@ -230,13 +225,13 @@
     }
     
     bufSize = status;
-    char *namebuf = (char *)NSZoneMalloc(NSDefaultMallocZone(), sizeof(char) * 
bufSize);
+    char *namebuf = (char *)malloc(sizeof(char) * bufSize);
     NSAssert(namebuf != NULL, @"unable to allocate memory");
     status = getxattr(fsPath, attrName, namebuf, bufSize, 0, xopts);
     
     if(status == -1){
         if(error) *error = [self xattrError:errno forPath:path];
-        NSZoneFree(NSDefaultMallocZone(), namebuf);
+        free(namebuf);
         return nil;
     }
     
@@ -258,20 +253,20 @@
             *error = err;
     }
     
-    if (namePrefix && [self isPlistData:attribute]) {
+    if (_namePrefix && [self isPlistData:attribute]) {
         id plist = [NSPropertyListSerialization propertyListWithData:attribute 
options:NSPropertyListImmutable format:NULL error:NULL];
         
         // even if it's a plist, it may not be a dictionary or have the key 
we're looking for
-        if (plist && [plist respondsToSelector:@selector(objectForKey:)] && 
[[plist objectForKey:wrapperKey] boolValue]) {
+        if (plist && [plist respondsToSelector:@selector(objectForKey:)] && 
[[plist objectForKey:_wrapperKey] boolValue]) {
             
-            NSString *uniqueValue = [plist objectForKey:uniqueKey];
-            NSUInteger i, numberOfFragments = [[plist 
objectForKey:fragmentsKey] unsignedIntegerValue];
+            NSString *uniqueValue = [plist objectForKey:_uniqueKey];
+            NSUInteger i, numberOfFragments = [[plist 
objectForKey:_fragmentsKey] unsignedIntegerValue];
 
             NSMutableData *buffer = [NSMutableData data];
             BOOL success = (nil != uniqueValue && numberOfFragments > 0);
             
             if (success == NO)
-                NSLog(@"failed to read unique key %@ for %lu fragments from 
property list.", uniqueKey, (long)numberOfFragments);
+                NSLog(@"failed to read unique key %@ for %lu fragments from 
property list.", _uniqueKey, (long)numberOfFragments);
             
             NSUInteger j = [attr rangeOfString:@"#"].location;
             NSString *suffix = j == NSNotFound || j == [attr length] - 1 ? @"" 
: [attr substringFromIndex:j];
@@ -286,7 +281,6 @@
                     subdata = [self copyRawExtendedAttributeNamed:oldName 
atPath:path traverseLink:follow error:&tmpError];
                     if (subdata)
                         suffix = @"";
-                    [oldName release];
                 }
                 if (nil == subdata) {
                     NSLog(@"failed to find subattribute %@ of %lu for 
attribute named %@. %@", name, (long)numberOfFragments, attr, [tmpError 
localizedDescription]);
@@ -293,13 +287,10 @@
                     success = NO;
                 } else {
                     [buffer appendData:subdata];
-                    [subdata release];
                 }
-                [name release];
             }
             
-            [attribute release];
-            attribute = success ? [[self bunzipData:buffer] retain] : nil;
+            attribute = success ? [self bunzipData:buffer] : nil;
             
             if (success == NO && NULL != error)
                 *error = [NSError errorWithDomain:SKNSkimNotesErrorDomain 
code:SKNReassembleAttributeFailedError userInfo:[NSDictionary 
dictionaryWithObjectsAndKeys:path, NSFilePathErrorKey, 
SKNLocalizedString(@"Failed to reassemble attribute value.", @"Error 
description"), NSLocalizedDescriptionKey, nil]];
@@ -308,7 +299,7 @@
 
         }
     }
-    return [attribute autorelease];
+    return attribute;
 }
 
 - (id)propertyListFromExtendedAttributeNamed:(NSString *)attr atPath:(NSString 
*)path traverseLink:(BOOL)traverse error:(NSError **)error;
@@ -360,7 +351,7 @@
     
     BOOL success;
 
-    if ((options & kSKNXattrNoSplitData) == 0 && namePrefix && [value length] 
> MAX_XATTR_LENGTH) {
+    if ((options & kSKNXattrNoSplitData) == 0 && _namePrefix && [value length] 
> MAX_XATTR_LENGTH) {
                     
         // compress to save space, and so we don't identify this as a plist 
when reading it (in case it really is plist data)
         value = [self bzipData:value];
@@ -368,7 +359,7 @@
         // this will be a unique identifier for the set of keys we're about to 
write (appending a counter to the UUID)
         NSString *uniqueValue = [self uniqueName];
         NSUInteger numberOfFragments = ([value length] / MAX_XATTR_LENGTH) + 
([value length] % MAX_XATTR_LENGTH ? 1 : 0);
-        NSDictionary *wrapper = [NSDictionary 
dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], wrapperKey, 
uniqueValue, uniqueKey, [NSNumber numberWithUnsignedInteger:numberOfFragments], 
fragmentsKey, nil];
+        NSDictionary *wrapper = [NSDictionary 
dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], _wrapperKey, 
uniqueValue, _uniqueKey, [NSNumber 
numberWithUnsignedInteger:numberOfFragments], _fragmentsKey, nil];
         NSData *wrapperData = [NSPropertyListSerialization 
dataWithPropertyList:wrapper format:NSPropertyListBinaryFormat_v1_0 options:0 
error:NULL];
         NSParameterAssert([wrapperData length] < MAX_XATTR_LENGTH && 
[wrapperData length] > 0);
         
@@ -396,7 +387,6 @@
             if (setxattr(fsPath, [name UTF8String], subdataPtr, subdataLen, 0, 
xopts)) {
                 NSLog(@"full data length of note named %@ was %lu, subdata 
length was %lu (failed on pass %lu)", name, (long)[value length], 
(long)subdataLen, (long)i);
             }
-            [name release];
         }
         
     } else {
@@ -424,7 +414,7 @@
         success = NO;
     } else {
         // if we don't split and the data is too long, compress the data using 
bzip to save space
-        if (((options & kSKNXattrNoSplitData) != 0 || namePrefix == nil) && 
(options & kSKNXattrNoCompress) == 0 && [data length] > MAX_XATTR_LENGTH)
+        if (((options & kSKNXattrNoSplitData) != 0 || _namePrefix == nil) && 
(options & kSKNXattrNoCompress) == 0 && [data length] > MAX_XATTR_LENGTH)
             data = [self bzipData:data];
         
         success = [self setExtendedAttributeNamed:attr toValue:data 
atPath:path options:options error:error];
@@ -461,25 +451,29 @@
 
     if(status != -1){
         bufSize = status;
-        char *namebuf = (char *)NSZoneMalloc(NSDefaultMallocZone(), 
sizeof(char) * bufSize);
+        char *namebuf = (char *)malloc(sizeof(char) * bufSize);
         NSAssert(namebuf != NULL, @"unable to allocate memory");
         status = getxattr(fsPath, attrName, namebuf, bufSize, 0, xopts);
         
-        if(status != -1){
+        if(status == -1){
             
+            free(namebuf);
+            
+        } else {
+            
             // let NSData worry about freeing the buffer
             NSData *attribute = [[NSData alloc] initWithBytesNoCopy:namebuf 
length:bufSize];
             
             id plist = nil;
             
-            if (namePrefix && [self isPlistData:attribute])
+            if (_namePrefix && [self isPlistData:attribute])
                 plist = [NSPropertyListSerialization 
propertyListWithData:attribute options:NSPropertyListImmutable format:NULL 
error:NULL];
             
             // even if it's a plist, it may not be a dictionary or have the 
key we're looking for
-            if (plist && [plist respondsToSelector:@selector(objectForKey:)] 
&& [[plist objectForKey:wrapperKey] boolValue]) {
+            if (plist && [plist respondsToSelector:@selector(objectForKey:)] 
&& [[plist objectForKey:_wrapperKey] boolValue]) {
                 
-                NSString *uniqueValue = [plist objectForKey:uniqueKey];
-                NSUInteger i, numberOfFragments = [[plist 
objectForKey:fragmentsKey] unsignedIntegerValue];
+                NSString *uniqueValue = [plist objectForKey:_uniqueKey];
+                NSUInteger i, numberOfFragments = [[plist 
objectForKey:_fragmentsKey] unsignedIntegerValue];
                 NSString *name;
                 
                 NSUInteger j = [attr rangeOfString:@"#"].location;
@@ -496,16 +490,12 @@
                         status = removexattr(fsPath, subAttrName, xopts);
                         if (status != -1)
                             suffix = @"";
-                        [oldName release];
                     }
                     if (status == -1) {
                         NSLog(@"failed to remove subattribute %@ of attribute 
named %@", name, attr);
                     }
-                    [name release];
                 }
             }
-            
-            [attribute release];
         }
     }
     
@@ -555,7 +545,7 @@
 {
     CFUUIDRef uuid = CFUUIDCreate(NULL);
     CFStringRef uuidString = CFUUIDCreateString(NULL, uuid);
-    NSString *uniqueName = [namePrefix stringByAppendingString:(NSString 
*)uuidString];
+    NSString *uniqueName = [_namePrefix stringByAppendingString:(__bridge 
NSString *)uuidString];
     CFRelease(uuid);
     CFRelease(uuidString);
     return uniqueName;
@@ -654,7 +644,6 @@
     } while(bzret != BZ_STREAM_END && NO == hadError);
     
     BZ2_bzCompressEnd(&stream);
-    [buffer release];
     
     return compressed;
 }
@@ -689,8 +678,7 @@
     } while(bzret != BZ_STREAM_END && NO == hadError);
     
     BZ2_bzDecompressEnd(&stream);
-    [buffer release];
-
+    
     return decompressed;
 }
 

Modified: trunk/SkimNotes/SKNPDFAnnotationNote.h
===================================================================
--- trunk/SkimNotes/SKNPDFAnnotationNote.h      2023-12-01 10:13:51 UTC (rev 
13819)
+++ trunk/SkimNotes/SKNPDFAnnotationNote.h      2023-12-03 10:34:00 UTC (rev 
13820)
@@ -78,56 +78,35 @@
 @interface SKNPDFAnnotationNote : PDFAnnotation
 #endif
 {
-    NSString *string;
-    PDFKitPlatformImage *image;
-    NSAttributedString *text;
+    NSString *_string;
+    PDFKitPlatformImage *_image;
+    NSAttributedString *_text;
 #if !defined(PDFKIT_PLATFORM_IOS)
-    NSTextStorage *textStorage;
-    NSArray *texts;
+    NSTextStorage *_textStorage;
+    NSArray *_texts;
 #endif
 }
 
 /*!
     @abstract   This is overridden and different from the contents.
-    @discussion This should give a short string value for the anchored note 
annotation. 
+    @discussion This should give a short string value for the anchored note 
annotation.  Setting this updates the contents using 
<code>updateContents</code>.
     @result     A string representing the string value associated with the 
annotation.
 */
-- (NSString *)string;
+@property (nonatomic, copy) NSString *string;
 
 /*!
-    @abstract   This is overridden and different from the contents.
-    @discussion This should set the short string value of the annotation.  
This updates the contents using <code>updateContents</code>.
-    @param      newString The new string value for the annotation.
-*/
-- (void)setString:(NSString *)newString;
-
-/*!
     @abstract   The rich text of the annotation.
-    @discussion This is the longer rich text contents of the anchored note 
annotation.
+    @discussion This is the longer rich text contents of the anchored note 
annotation.  Setting this updates the contents using 
<code>updateContents</code>.
 */
-- (NSAttributedString *)text;
+@property (nonatomic, copy) NSAttributedString *text;
 
 /*!
-    @abstract   Sets the rich text of the annotation.
-    @discussion This should set the longer rich text contents of the 
annotation.  This updates the contents using <code>updateContents</code>.
-    @param      newText The new rich text value for the annotation.
-*/
-- (void)setText:(NSAttributedString *)newText;
-
-/*!
     @abstract   The image of the annotation.
     @discussion 
 */
-- (PDFKitPlatformImage *)image;
+@property (nonatomic, retain) PDFKitPlatformImage *image;
 
 /*!
-    @abstract   Sets the image of the annotation.
-    @discussion 
-    @param      newImage The new image for the annotation.
-*/
-- (void)setImage:(PDFKitPlatformImage *)newImage;
-
-/*!
     @abstract   Synchronizes the contents of the annotation with the string 
and text.
     @discussion This sets the contents to the string value and the text 
appended, separated by a double space.
 */

Modified: trunk/SkimNotes/SKNPDFAnnotationNote.m
===================================================================
--- trunk/SkimNotes/SKNPDFAnnotationNote.m      2023-12-01 10:13:51 UTC (rev 
13819)
+++ trunk/SkimNotes/SKNPDFAnnotationNote.m      2023-12-03 10:34:00 UTC (rev 
13820)
@@ -68,8 +68,9 @@
 @end
 #endif
 
-@interface SKNPDFAnnotationNote (SKNPrivate)
-- (NSTextStorage *)mutableText;
+@interface SKNPDFAnnotationNote ()
+@property (nonatomic, readonly) NSTextStorage *mutableText;
+@property (nonatomic, retain) NSArray *texts;
 @end
 
 #endif
@@ -80,13 +81,19 @@
 
 @implementation SKNPDFAnnotationNote
 
+@synthesize string = _string;
+@synthesize text = _text;
+@dynamic image;
+@dynamic mutableText;
+@synthesize texts = _texts;
+
 - (void)updateContents {
     NSMutableString *contents = [NSMutableString string];
-    if ([string length])
-        [contents appendString:string];
-    if ([text length]) {
+    if ([_string length])
+        [contents appendString:_string];
+    if ([_text length]) {
         [contents appendString:@"  "];
-        [contents appendString:[text string]];
+        [contents appendString:[_text string]];
     }
     [super setContents:contents];
 }
@@ -101,13 +108,13 @@
         NSAttributedString *aText = [dict 
objectForKey:SKNPDFAnnotationTextKey];
         PDFKitPlatformImage *anImage = [dict 
objectForKey:SKNPDFAnnotationImageKey];
         if ([anImage isKindOfClass:imageClass])
-            image = [anImage retain];
+            _image = anImage;
         else if ([anImage isKindOfClass:dataClass])
-            image = [[PDFKitPlatformImage alloc] initWithData:(NSData 
*)anImage];
+            _image = [[PDFKitPlatformImage alloc] initWithData:(NSData 
*)anImage];
         if ([aText isKindOfClass:stringClass])
-            aText = [[[NSAttributedString alloc] initWithString:(NSString 
*)aText] autorelease];
+            aText = [[NSAttributedString alloc] initWithString:(NSString 
*)aText];
         else if ([aText isKindOfClass:dataClass])
-            aText = [[[NSAttributedString alloc] initWithData:(NSData *)aText 
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL] 
autorelease];
+            aText = [[NSAttributedString alloc] initWithData:(NSData *)aText 
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
         if ([aText isKindOfClass:attrStringClass])
             [self setText:aText];
         [self updateContents];
@@ -115,18 +122,6 @@
     return self;
 }
 
-- (void)dealloc {
-#if !defined(PDFKIT_PLATFORM_IOS)
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-    [textStorage release];
-    [texts release];
-#endif
-    [string release];
-    [text release];
-    [image release];
-    [super dealloc];
-}
-
 - (NSDictionary *)SkimNoteProperties{
     NSMutableDictionary *dict = [self genericSkimNoteProperties];
     [dict setValue:[NSNumber numberWithInteger:[self iconType]] 
forKey:SKNPDFAnnotationIconTypeKey];
@@ -139,40 +134,19 @@
     return SKNNoteString;
 }
 
-- (NSString *)string {
-    return string;
-}
-
-- (void)setString:(NSString *)newString {
-    if (string != newString) {
-        [string release];
-        string = [newString copy];
+- (void)setString:(NSString *)string {
+    if (_string != string) {
+        _string = [string copy];
         // update the contents to string + text
         [self updateContents];
     }
 }
 
-- (PDFKitPlatformImage *)image {
-    return image;
-}
-
-- (void)setImage:(PDFKitPlatformImage *)newImage {
-    if (image != newImage) {
-        [image release];
-        image = [newImage retain];
-    }
-}
-
-- (NSAttributedString *)text {
-    return text;
-}
-
 #if defined(PDFKIT_PLATFORM_IOS)
 
-- (void)setText:(NSAttributedString *)newText {
-    if (text != newText) {
-        [text release];
-        text = [newText copy];
+- (void)setText:(NSAttributedString *)text {
+    if (_text != text) {
+        _text = [text copy];
         // update the contents to string + text
         [self updateContents];
     }
@@ -180,13 +154,13 @@
 
 #else
 
-- (void)setText:(NSAttributedString *)newText {
-    if ([self mutableText] != newText) {
+- (void)setText:(NSAttributedString *)text {
+    if ([self mutableText] != text) {
         // edit the textStorage, this will trigger KVO and update the text 
automatically
-        if (newText)
-            [textStorage replaceCharactersInRange:NSMakeRange(0, [textStorage 
length]) withAttributedString:newText];
+        if (text)
+            [_textStorage replaceCharactersInRange:NSMakeRange(0, 
[_textStorage length]) withAttributedString:text];
         else
-            [textStorage deleteCharactersInRange:NSMakeRange(0, [textStorage 
length])];
+            [_textStorage deleteCharactersInRange:NSMakeRange(0, [_textStorage 
length])];
     }
 }
 
@@ -204,24 +178,23 @@
 
 - (void)textDidChange:(NSNotification *)notification {
     // texts should be an array of objects wrapping the text of the note, used 
by Skim to provide a data source for the children in the outlineView
-    [texts makeObjectsPerformSelector:@selector(willChangeValueForKey:) 
withObject:SKNPDFAnnotationTextKey];
+    [_texts makeObjectsPerformSelector:@selector(willChangeValueForKey:) 
withObject:SKNPDFAnnotationTextKey];
     // trigger KVO manually
     [self willChangeValueForKey:SKNPDFAnnotationTextKey];
     // update the text
-    [text release];
-    text = [[NSAttributedString alloc] initWithAttributedString:textStorage];
+    _text = [[NSAttributedString alloc] initWithAttributedString:_textStorage];
     [self didChangeValueForKey:SKNPDFAnnotationTextKey];
-    [texts makeObjectsPerformSelector:@selector(didChangeValueForKey:) 
withObject:SKNPDFAnnotationTextKey];
+    [_texts makeObjectsPerformSelector:@selector(didChangeValueForKey:) 
withObject:SKNPDFAnnotationTextKey];
     // update the contents to string + text
     [self updateContents];
 }
 
 - (NSTextStorage *)mutableText {
-    if (textStorage == nil) {
-        textStorage = [[NSTextStorage alloc] init];
-        [[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(textDidChange:) 
name:NSTextStorageDidProcessEditingNotification object:textStorage];
+    if (_textStorage == nil) {
+        _textStorage = [[NSTextStorage alloc] init];
+        [[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(textDidChange:) 
name:NSTextStorageDidProcessEditingNotification object:_textStorage];
     }
-    return textStorage;
+    return _textStorage;
 }
 
 // private method called by -drawWithBox: before to 10.12, made public on 
10.12, now calling -drawWithBox:

Modified: trunk/SkimNotes/SKNSkimReader.h
===================================================================
--- trunk/SkimNotes/SKNSkimReader.h     2023-12-01 10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/SKNSkimReader.h     2023-12-03 10:34:00 UTC (rev 13820)
@@ -40,15 +40,15 @@
 
 
 @interface SKNSkimReader : NSObject {
-    NSString *agentIdentifier;
+    NSString *_agentIdentifier;
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-    NSConnection *connection;
+    NSConnection *_connection;
 #pragma clang diagnostic pop
-    id agent;
+    id _agent;
 }
 
-@property (class, nonatomic, readonly) id sharedReader;
+@property (class, nonatomic, readonly) SKNSkimReader *sharedReader;
 
 // this should only be set before any of the following calls is made
 @property (nonatomic, retain) NSString *agentIdentifier;

Modified: trunk/SkimNotes/SKNSkimReader.m
===================================================================
--- trunk/SkimNotes/SKNSkimReader.m     2023-12-01 10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/SKNSkimReader.m     2023-12-03 10:34:00 UTC (rev 13820)
@@ -45,7 +45,7 @@
 
 @synthesize agentIdentifier;
 
-+ (id)sharedReader {
++ (SKNSkimReader *)sharedReader {
     static id sharedReader = nil;
     static dispatch_once_t onceToken = 0;
     dispatch_once(&onceToken, ^{
@@ -57,14 +57,14 @@
 - (void)destroyConnection {
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-    [[NSNotificationCenter defaultCenter] removeObserver:self 
name:NSConnectionDidDieNotification object:connection];
+    [[NSNotificationCenter defaultCenter] removeObserver:self 
name:NSConnectionDidDieNotification object:_connection];
 #pragma clang diagnostic pop
-    agent = nil;
+    _agent = nil;
     
-    [[connection receivePort] invalidate];
-    [[connection sendPort] invalidate];
-    [connection invalidate];
-    connection = nil;
+    [[_connection receivePort] invalidate];
+    [[_connection sendPort] invalidate];
+    [_connection invalidate];
+    _connection = nil;
 }
 
 - (void)dealloc {
@@ -72,9 +72,9 @@
 }
 
 - (void)setAgentIdentifier:(NSString *)identifier {
-    NSAssert(connection == nil, @"agentIdentifier must be set before 
connecting");
-    if (connection == nil && agentIdentifier != identifier) {
-        agentIdentifier = identifier;
+    NSAssert(_connection == nil, @"agentIdentifier must be set before 
connecting");
+    if (_connection == nil && _agentIdentifier != identifier) {
+        _agentIdentifier = identifier;
     }
 }
 
@@ -152,34 +152,34 @@
         int maxTries = 5;
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-        connection = [NSConnection connectionWithRegisteredName:[self 
agentIdentifier] host:nil];
+        _connection = [NSConnection connectionWithRegisteredName:[self 
agentIdentifier] host:nil];
 #pragma clang diagnostic pop
         
         // if we try to read data before the server is fully set up, 
connection will still be nil
-        while (nil == connection && maxTries--) { 
+        while (nil == _connection && maxTries--) {
             [NSThread sleepUntilDate:[NSDate 
dateWithTimeIntervalSinceNow:0.1]];
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-            connection = [NSConnection connectionWithRegisteredName:[self 
agentIdentifier] host:nil];
+            _connection = [NSConnection connectionWithRegisteredName:[self 
agentIdentifier] host:nil];
 #pragma clang diagnostic pop
         }
         
-        if (connection) {
+        if (_connection) {
             
             // keep an eye on the connection from our end, so we can retain 
the proxy object
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-            [[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(handleConnectionDied:) name:NSConnectionDidDieNotification 
object:connection];
+            [[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(handleConnectionDied:) name:NSConnectionDidDieNotification 
object:_connection];
 #pragma clang diagnostic pop
             
             // if we don't set these explicitly, timeout never seems to take 
place
-            [connection setRequestTimeout:AGENT_TIMEOUT];
-            [connection setReplyTimeout:AGENT_TIMEOUT];
+            [_connection setRequestTimeout:AGENT_TIMEOUT];
+            [_connection setReplyTimeout:AGENT_TIMEOUT];
             
             @try {
-                id server = [connection rootProxy];
+                id server = [_connection rootProxy];
                 [server 
setProtocolForProxy:@protocol(SKNAgentListenerProtocol)];
-                agent = server;
+                _agent = server;
             }
             @catch(id exception) {
                 NSLog(@"Error: exception \"%@\" caught when contacting 
SkimNotesAgent", exception);
@@ -198,7 +198,7 @@
         ([ws type:fileType conformsToType:(__bridge NSString *)kUTTypePDF] ||
          [ws type:fileType conformsToType:@"net.sourceforge.skim-app.pdfd"] ||
          [ws type:fileType 
conformsToType:@"net.sourceforge.skim-app.skimnotes"])) {
-        if (nil == connection)
+        if (nil == _connection)
             [self establishConnection];
         return YES;
     }
@@ -209,7 +209,7 @@
     NSData *data = nil;
     if ([self connectAndCheckTypeOfFile:fileURL]) {
         @try{
-            data = [agent SkimNotesAtPath:[fileURL path]];
+            data = [_agent SkimNotesAtPath:[fileURL path]];
         }
         @catch(id exception){
             data = nil;
@@ -224,7 +224,7 @@
     NSData *data = nil;
     if ([self connectAndCheckTypeOfFile:fileURL]) {
         @try{
-            data = [agent RTFNotesAtPath:[fileURL path]];
+            data = [_agent RTFNotesAtPath:[fileURL path]];
         }
         @catch(id exception){
             data = nil;
@@ -239,7 +239,7 @@
     NSData *textData = nil;
     if ([self connectAndCheckTypeOfFile:fileURL]) {
         @try{
-            textData = [agent textNotesAtPath:[fileURL path] 
encoding:NSUnicodeStringEncoding];
+            textData = [_agent textNotesAtPath:[fileURL path] 
encoding:NSUnicodeStringEncoding];
         }
         @catch(id exception){
             textData = nil;

Modified: trunk/SkimNotes/SKNUtilities.m
===================================================================
--- trunk/SkimNotes/SKNUtilities.m      2023-12-01 10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/SKNUtilities.m      2023-12-03 10:34:00 UTC (rev 13820)
@@ -92,7 +92,7 @@
             pageIndex = 0;
         
         if ([text isKindOfClass:[NSData class]])
-            text = [[[NSAttributedString alloc] initWithData:(NSData *)text 
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL] 
autorelease];
+            text = [[NSAttributedString alloc] initWithData:(NSData *)text 
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
         
         [textString appendFormat:@"* %@, page %lu\n\n", type, (long)pageIndex 
+ 1];
         if ([string length]) {
@@ -108,7 +108,7 @@
 }
 
 NSData *SKNSkimRTFNotes(NSArray *noteDicts) {
-    NSMutableAttributedString *attrString = [[[NSMutableAttributedString 
alloc] init] autorelease];
+    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] 
init];
     
     for (NSDictionary *dict in noteDicts) {
         NSString *type = [dict objectForKey:NOTE_TYPE_KEY];
@@ -124,7 +124,7 @@
             pageIndex = 0;
         
         if ([text isKindOfClass:[NSData class]])
-            text = [[[NSAttributedString alloc] initWithData:(NSData *)text 
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL] 
autorelease];
+            text = [[NSAttributedString alloc] initWithData:(NSData *)text 
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
         
         [attrString replaceCharactersInRange:NSMakeRange([attrString length], 
0) withString:[NSString stringWithFormat:@"* %@, page %lu\n\n", type, 
(long)pageIndex + 1]];
         if ([string length]) {
@@ -153,52 +153,37 @@
     return YES;
 }
 
-static NSArray *SKNCreateArrayFromColor(SKNColor *color, NSMapTable **colors, 
NSMutableSet **arrays) {
+static NSArray *SKNArrayFromColor(SKNColor *color, NSMapTable *colors) {
+    NSArray *array = [colors objectForKey:color];
+    if (array)
+        return array;
     if ([color isKindOfClass:[SKNColor class]]) {
-        NSArray *array = [*colors objectForKey:color];
-        if (array == nil) {
 #if defined(SKIMNOTES_PLATFORM_IOS)
-            if (CGColorSpaceGetModel(CGColorGetColorSpace([color CGColor])) == 
kCGColorSpaceModelMonochrome) {
-                CGFloat w = 0.0, a = 1.0;
-                [color getWhite:&w alpha:&a];
-                array = [[NSArray alloc] initWithObjects:[NSNumber 
numberWithDouble:w], [NSNumber numberWithDouble:a], nil];
-            } else {
-                CGFloat r = 0.0, g = 0.0, b = 0.0, a = 1.0;
-                [color getRed:&r green:&g blue:&b alpha:&a];
-                array = [[NSArray alloc] initWithObjects:[NSNumber 
numberWithDouble:r], [NSNumber numberWithDouble:g], [NSNumber 
numberWithDouble:b], [NSNumber numberWithDouble:a], nil];
-            }
+        if (CGColorSpaceGetModel(CGColorGetColorSpace([color CGColor])) == 
kCGColorSpaceModelMonochrome) {
+            CGFloat w = 0.0, a = 1.0;
+            [color getWhite:&w alpha:&a];
+            array = [[NSArray alloc] initWithObjects:[NSNumber 
numberWithDouble:w], [NSNumber numberWithDouble:a], nil];
+        } else {
+            CGFloat r = 0.0, g = 0.0, b = 0.0, a = 1.0;
+            [color getRed:&r green:&g blue:&b alpha:&a];
+            array = [[NSArray alloc] initWithObjects:[NSNumber 
numberWithDouble:r], [NSNumber numberWithDouble:g], [NSNumber 
numberWithDouble:b], [NSNumber numberWithDouble:a], nil];
+        }
 #else
-            if ([[color colorSpace] colorSpaceModel] == NSGrayColorSpaceModel) 
{
-                CGFloat w = 0.0, a = 1.0;
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
-                if ([NSColorSpace 
respondsToSelector:@selector(genericGamma22GrayColorSpace)] == NO)
-                    [[color colorUsingColorSpace:[NSColorSpace 
genericGrayColorSpace]] getWhite:&w alpha:&a];
-                else
-#endif
-                [[color colorUsingColorSpace:[NSColorSpace 
genericGamma22GrayColorSpace]] getWhite:&w alpha:&a];
-                array = [[NSArray alloc] initWithObjects:[NSNumber 
numberWithDouble:w], [NSNumber numberWithDouble:a], nil];
-            } else {
-                CGFloat r = 0.0, g = 0.0, b = 0.0, a = 1.0;
-                [[color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]] 
getRed:&r green:&g blue:&b alpha:&a];
-                array = [[NSArray alloc] initWithObjects:[NSNumber 
numberWithDouble:r], [NSNumber numberWithDouble:g], [NSNumber 
numberWithDouble:b], [NSNumber numberWithDouble:a], nil];
-            }
-#endif
-            if (*colors == nil)
-                *colors = [[NSMapTable alloc] 
initWithKeyOptions:NSPointerFunctionsStrongMemory | 
NSPointerFunctionsObjectPersonality valueOptions:NSPointerFunctionsStrongMemory 
| NSPointerFunctionsObjectPersonality capacity:0];
-            [*colors setObject:array forKey:color];
+        if ([[color colorSpace] colorSpaceModel] == NSGrayColorSpaceModel) {
+            CGFloat w = 0.0, a = 1.0;
+            [[color colorUsingColorSpace:[NSColorSpace 
genericGamma22GrayColorSpace]] getWhite:&w alpha:&a];
+            array = [[NSArray alloc] initWithObjects:[NSNumber 
numberWithDouble:w], [NSNumber numberWithDouble:a], nil];
         } else {
-            [array retain];
+            CGFloat r = 0.0, g = 0.0, b = 0.0, a = 1.0;
+            [[color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]] 
getRed:&r green:&g blue:&b alpha:&a];
+            array = [[NSArray alloc] initWithObjects:[NSNumber 
numberWithDouble:r], [NSNumber numberWithDouble:g], [NSNumber 
numberWithDouble:b], [NSNumber numberWithDouble:a], nil];
         }
+#endif
+        [colors setObject:array forKey:color];
         return array;
     } else if (SKNIsNumberArray(color)) {
-        NSArray *array = [*arrays member:color];
-        if (array == nil) {
-            if (*arrays == nil)
-                *arrays = [[NSMutableSet alloc] init];
-            [*arrays addObject:color];
-            array = (NSArray *)color;
-        }
-        return [array retain];
+        [colors setObject:color forKey:color];
+        return (NSArray *)color;
     } else {
         return nil;
     }
@@ -224,13 +209,8 @@
 #if defined(SKIMNOTES_PLATFORM_IOS)
             return [UIColor colorWithWhite:c[0] alpha:c[1]];
 #else
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
-            if ([NSColorSpace 
respondsToSelector:@selector(genericGamma22GrayColorSpace)] == NO)
-                return [NSColor colorWithColorSpace:[NSColorSpace 
genericGrayColorSpace] components:c count:2];
-            else
+            return [NSColor colorWithColorSpace:[NSColorSpace 
genericGamma22GrayColorSpace] components:c count:2];
 #endif
-                return [NSColor colorWithColorSpace:[NSColorSpace 
genericGamma22GrayColorSpace] components:c count:2];
-#endif
         } else {
             return [SKNColor clearColor];
         }
@@ -259,15 +239,15 @@
                     id value;
                     if ((value = [dict objectForKey:NOTE_COLOR_KEY])) {
                         value = SKNColorFromArray(value);
-                        [dict setObject:value forKey:NOTE_COLOR_KEY];
+                        [dict setValue:value forKey:NOTE_COLOR_KEY];
                     }
                     if ((value = [dict objectForKey:NOTE_INTERIOR_COLOR_KEY])) 
{
                         value = SKNColorFromArray(value);
-                        [dict setObject:value forKey:NOTE_INTERIOR_COLOR_KEY];
+                        [dict setValue:value forKey:NOTE_INTERIOR_COLOR_KEY];
                     }
                     if ((value = [dict objectForKey:NOTE_FONT_COLOR_KEY])) {
                         value = SKNColorFromArray(value);
-                        [dict setObject:value forKey:NOTE_FONT_COLOR_KEY];
+                        [dict setValue:value forKey:NOTE_FONT_COLOR_KEY];
                     }
                     if ((value = [dict objectForKey:NOTE_FONT_NAME_KEY])) {
                         NSNumber *fontSize = [dict 
objectForKey:NOTE_FONT_SIZE_KEY];
@@ -282,12 +262,7 @@
                     if ((value = [dict objectForKey:NOTE_TEXT_KEY])) {
                         if ([value isKindOfClass:[NSData class]]) {
                             value = [[NSAttributedString alloc] 
initWithData:value options:[NSDictionary dictionary] documentAttributes:NULL 
error:NULL];
-                            if (value) {
-                                [dict setObject:value forKey:NOTE_TEXT_KEY];
-                                [value release];
-                            } else {
-                                [dict removeObjectForKey:NOTE_TEXT_KEY];
-                            }
+                            [dict setValue:value forKey:NOTE_TEXT_KEY];
                         } else if ([value isKindOfClass:[NSAttributedString 
class]] == NO) {
                             [dict removeObjectForKey:NOTE_TEXT_KEY];
                         }
@@ -295,8 +270,7 @@
                     if ((value = [dict objectForKey:NOTE_IMAGE_KEY])) {
                         if ([value isKindOfClass:[NSData class]]) {
                             value = [[SKNImage alloc] initWithData:value];
-                            [dict setObject:value forKey:NOTE_IMAGE_KEY];
-                            [value release];
+                            [dict setValue:value forKey:NOTE_IMAGE_KEY];
                         } else if ([value isKindOfClass:[SKNImage class]] == 
NO) {
                             [dict removeObjectForKey:NOTE_IMAGE_KEY];
                         }
@@ -321,25 +295,21 @@
 #endif
         if (asPlist) {
             NSMutableArray *array = [[NSMutableArray alloc] init];
-            NSMapTable *colors = nil;
-            NSMutableSet *arrays = nil;
+            NSMapTable *colors = [[NSMapTable alloc] 
initWithKeyOptions:NSPointerFunctionsStrongMemory | 
NSPointerFunctionsObjectPersonality valueOptions:NSPointerFunctionsStrongMemory 
| NSPointerFunctionsObjectPersonality capacity:0];
             for (NSDictionary *noteDict in noteDicts) {
                 NSMutableDictionary *dict = [noteDict mutableCopy];
                 id value;
                 if ((value = [dict objectForKey:NOTE_COLOR_KEY])) {
-                    value = SKNCreateArrayFromColor(value, &colors, &arrays);
-                    [dict setObject:value forKey:NOTE_COLOR_KEY];
-                    [value release];
+                    value = SKNArrayFromColor(value, colors);
+                    [dict setValue:value forKey:NOTE_COLOR_KEY];
                 }
                 if ((value = [dict objectForKey:NOTE_INTERIOR_COLOR_KEY])) {
-                    value = SKNCreateArrayFromColor(value, &colors, &arrays);
-                    [dict setObject:value forKey:NOTE_INTERIOR_COLOR_KEY];
-                    [value release];
+                    value = SKNArrayFromColor(value, colors);
+                    [dict setValue:value forKey:NOTE_INTERIOR_COLOR_KEY];
                 }
                 if ((value = [dict objectForKey:NOTE_FONT_COLOR_KEY])) {
-                    value = SKNCreateArrayFromColor(value, &colors, &arrays);
-                    [dict setObject:value forKey:NOTE_FONT_COLOR_KEY];
-                    [value release];
+                    value = SKNArrayFromColor(value, colors);
+                    [dict setValue:value forKey:NOTE_FONT_COLOR_KEY];
                 }
                 if ((value = [dict objectForKey:NOTE_FONT_KEY])) {
                     if ([value isKindOfClass:[SKNFont class]]) {
@@ -384,12 +354,8 @@
                     }
                 }
                 [array addObject:dict];
-                [dict release];
             }
             data = [NSPropertyListSerialization dataWithPropertyList:array 
format:NSPropertyListBinaryFormat_v1_0 options:0 error:NULL];
-            [array release];
-            [colors release];
-            [arrays release];
         } else {
             data = [NSKeyedArchiver archivedDataWithRootObject:noteDicts];
         }

Modified: trunk/SkimNotes/SKNXPCSkimReader.h
===================================================================
--- trunk/SkimNotes/SKNXPCSkimReader.h  2023-12-01 10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/SKNXPCSkimReader.h  2023-12-03 10:34:00 UTC (rev 13820)
@@ -40,13 +40,13 @@
 
 
 @interface SKNXPCSkimReader : NSObject {
-    NSString *agentIdentifier;
-    NSXPCConnection *connection;
-    id agent;
-    BOOL synchronous;
+    NSString *_agentIdentifier;
+    NSXPCConnection *_connection;
+    id _agent;
+    BOOL _synchronous;
 }
 
-@property (class, nonatomic, readonly) id sharedReader;
+@property (class, nonatomic, readonly) SKNXPCSkimReader *sharedReader;
 
 // this should only be set before any of the following calls is made
 @property (nonatomic, retain) NSString *agentIdentifier;

Modified: trunk/SkimNotes/SKNXPCSkimReader.m
===================================================================
--- trunk/SkimNotes/SKNXPCSkimReader.m  2023-12-01 10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/SKNXPCSkimReader.m  2023-12-03 10:34:00 UTC (rev 13820)
@@ -42,9 +42,9 @@
 
 @implementation SKNXPCSkimReader
 
-@synthesize agentIdentifier;
+@synthesize agentIdentifier=_agentIdentifier;
 
-+ (id)sharedReader {
++ (SKNXPCSkimReader *)sharedReader {
     static id sharedReader = nil;
     static dispatch_once_t onceToken = 0;
     dispatch_once(&onceToken, ^{
@@ -54,10 +54,10 @@
 }
 
 - (void)destroyConnection {
-    agent = nil;
+    _agent = nil;
     
-    [connection invalidate];
-    connection = nil;
+    [_connection invalidate];
+    _connection = nil;
 }
 
 - (void)dealloc {
@@ -65,9 +65,9 @@
 }
 
 - (void)setAgentIdentifier:(NSString *)identifier {
-    NSAssert(connection == nil, @"agentIdentifier must be set before 
connecting");
-    if (connection == nil && agentIdentifier != identifier) {
-        agentIdentifier = identifier;
+    NSAssert(_connection == nil, @"agentIdentifier must be set before 
connecting");
+    if (_connection == nil && _agentIdentifier != identifier) {
+        _agentIdentifier = identifier;
     }
 }
 
@@ -156,23 +156,23 @@
 
 - (void)establishSynchronousConnection:(BOOL)sync {
     if ([self launchedTask]) {
-        connection = [[NSXPCConnection alloc] initWithMachServiceName:[self 
agentIdentifier] options:0];
-        [connection setRemoteObjectInterface:[NSXPCInterface 
interfaceWithProtocol:@protocol(SKNXPCAgentListenerProtocol)]];
+        _connection = [[NSXPCConnection alloc] initWithMachServiceName:[self 
agentIdentifier] options:0];
+        [_connection setRemoteObjectInterface:[NSXPCInterface 
interfaceWithProtocol:@protocol(SKNXPCAgentListenerProtocol)]];
         __weak SKNXPCSkimReader *weakSelf = self;
-        [connection setInvalidationHandler:^{
+        [_connection setInvalidationHandler:^{
             [weakSelf destroyConnection];
         }];
         if (sync)
-            agent = [connection 
synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error){}];
+            _agent = [_connection 
synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error){}];
         else
-            agent = [connection remoteObjectProxy];
-        synchronous = sync;
-        [connection resume];
+            _agent = [_connection remoteObjectProxy];
+        _synchronous = sync;
+        [_connection resume];
     }
 }
 
 - (BOOL)connectAndCheckTypeOfFile:(NSURL *)fileURL synchronous:(BOOL)sync {
-    if (connection && synchronous != sync) {
+    if (_connection && _synchronous != sync) {
         NSLog(@"attempt to mix synchronous and asynchronous skim notes 
retrieval");
         return NO;
     }
@@ -185,7 +185,7 @@
         ([ws type:fileType conformsToType:(__bridge NSString *)kUTTypePDF] ||
          [ws type:fileType conformsToType:@"net.sourceforge.skim-app.pdfd"] ||
          [ws type:fileType 
conformsToType:@"net.sourceforge.skim-app.skimnotes"])) {
-        if (nil == connection)
+        if (nil == _connection)
             [self establishSynchronousConnection:sync];
         return YES;
     }
@@ -195,7 +195,7 @@
 - (NSData *)SkimNotesAtURL:(NSURL *)fileURL {
     __block NSData *data = nil;
     if ([self connectAndCheckTypeOfFile:fileURL synchronous:YES])
-        [agent readSkimNotesAtURL:fileURL reply:^(NSData *outData){ data = 
outData; }];
+        [_agent readSkimNotesAtURL:fileURL reply:^(NSData *outData){ data = 
outData; }];
     return data;
 }
 
@@ -202,7 +202,7 @@
 - (NSData *)RTFNotesAtURL:(NSURL *)fileURL {
     __block NSData *data = nil;
     if ([self connectAndCheckTypeOfFile:fileURL synchronous:YES])
-        [agent readRTFNotesAtURL:fileURL reply:^(NSData *outData){ data = 
outData; }];
+        [_agent readRTFNotesAtURL:fileURL reply:^(NSData *outData){ data = 
outData; }];
     return data;
 }
 
@@ -209,13 +209,13 @@
 - (NSString *)textNotesAtURL:(NSURL *)fileURL {
     __block NSString *string = nil;
     if ([self connectAndCheckTypeOfFile:fileURL synchronous:YES])
-        [agent readTextNotesAtURL:fileURL reply:^(NSString *outString){ string 
= outString; }];
+        [_agent readTextNotesAtURL:fileURL reply:^(NSString *outString){ 
string = outString; }];
     return string;
 }
 
 - (void)readSkimNotesAtURL:(NSURL *)fileURL reply:(void (^)(NSData *))reply {
     if ([self connectAndCheckTypeOfFile:fileURL synchronous:NO])
-        [agent readSkimNotesAtURL:fileURL reply:reply];
+        [_agent readSkimNotesAtURL:fileURL reply:reply];
     else
         reply(nil);
 }
@@ -222,7 +222,7 @@
 
 - (void)readRTFNotesAtURL:(NSURL *)fileURL reply:(void (^)(NSData *))reply {
     if ([self connectAndCheckTypeOfFile:fileURL synchronous:NO])
-        [agent readRTFNotesAtURL:fileURL reply:reply];
+        [_agent readRTFNotesAtURL:fileURL reply:reply];
     else
         reply(nil);
 }
@@ -229,7 +229,7 @@
 
 - (void)readTextNotesAtURL:(NSURL *)fileURL reply:(void (^)(NSString *))reply {
     if ([self connectAndCheckTypeOfFile:fileURL synchronous:NO])
-        [agent readTextNotesAtURL:fileURL reply:reply];
+        [_agent readTextNotesAtURL:fileURL reply:reply];
     else
         reply(nil);
 }

Modified: trunk/SkimNotes/skimnotes.m
===================================================================
--- trunk/SkimNotes/skimnotes.m 2023-12-01 10:13:51 UTC (rev 13819)
+++ trunk/SkimNotes/skimnotes.m 2023-12-03 10:34:00 UTC (rev 13820)
@@ -231,391 +231,383 @@
 }
 
 int main (int argc, const char * argv[]) {
-    NSAutoreleasePool *pool = [NSAutoreleasePool new];
- 
-    NSArray *args = [[NSProcessInfo processInfo] arguments];
-    
-    if (argc < 2) {
-        WRITE_ERROR;
-        [pool release];
-        exit(EXIT_FAILURE);
-    }
-    
-    NSInteger action = SKNActionForName([args objectAtIndex:1]);
-    
     BOOL success = NO;
     
-    if (action == SKNActionUnknown) {
+    @autoreleasepool {
+        NSArray *args = [[NSProcessInfo processInfo] arguments];
         
-        WRITE_ERROR;
-        [pool release];
-        exit(EXIT_FAILURE);
-        
-    } else if (action == SKNActionAgent) {
-        
-        BOOL isXPC = ([args count] > 2 && [[args objectAtIndex:2] 
isEqualToString:XPC_OPTION_STRING]);
-        NSString *serverName = [args count] > (isXPC ? 3 : 2) ? [args 
lastObject] : nil;
-        
-        SKNAgentListener *listener = [[SKNAgentListener alloc] 
initWithServerName:serverName xpc:isXPC];
-        
-        NSRunLoop *rl = [NSRunLoop currentRunLoop];
-        BOOL didRun;
-        
-        do {
-            [pool release];
-            pool = [NSAutoreleasePool new];
-            didRun = [rl runMode:NSDefaultRunLoopMode beforeDate:[NSDate 
distantFuture]];
-        } while (listener && didRun);
-        
-        [listener release];
-        
-        success = YES;
-        
-    } else if (action == SKNActionProtocol) {
-        
-        if ([args count] > 2 && [[args objectAtIndex:2] 
isEqualToString:XPC_OPTION_STRING]) {
-            WRITE_OUT(xpcProtocolStr);
-        } else {
-            WRITE_OUT(protocolStr);
-        }
-        
-    } else if (action == SKNActionHelp) {
-        
-        NSInteger helpAction = SKNActionForName([args count] > 2 ? [args 
objectAtIndex:2] : @"");
-        
-        switch (helpAction) {
-            case SKNActionUnknown:
-                WRITE_OUT_VERSION(usageStr);
-                break;
-            case SKNActionGet:
-                WRITE_OUT(getHelpStr);
-                break;
-            case SKNActionSet:
-                WRITE_OUT(setHelpStr);
-                break;
-            case SKNActionRemove:
-                WRITE_OUT(removeHelpStr);
-                break;
-            case SKNActionTest:
-                WRITE_OUT(testHelpStr);
-                break;
-            case SKNActionConvert:
-                WRITE_OUT(convertHelpStr);
-                break;
-            case SKNActionFormat:
-                WRITE_OUT(formatHelpStr);
-                break;
-            case SKNActionOffset:
-                WRITE_OUT(offsetHelpStr);
-                break;
-            case SKNActionAgent:
-                WRITE_OUT(agentHelpStr);
-                break;
-            case SKNActionProtocol:
-                WRITE_OUT(protocolHelpStr);
-                break;
-            case SKNActionVersion:
-                WRITE_OUT(versionHelpStr);
-                break;
-            case SKNActionHelp:
-                WRITE_OUT(helpHelpStr);
-                break;
-        }
-        success = YES;
-        
-    } else if (action == SKNActionVersion) {
-        
-        WRITE_OUT(versionStr);
-        
-    } else {
-        
-        if (argc < 3) {
+        if (argc < 2) {
             WRITE_ERROR;
-            [pool release];
             exit(EXIT_FAILURE);
         }
         
-        NSInteger format = SKNFormatAuto;
-        CGFloat dx = 0.0, dy = 0.0;
-        SKNSyncability syncable = SKNAnySyncable;
-        int offset = 2;
+        NSInteger action = SKNActionForName([args objectAtIndex:1]);
         
-        if (action == SKNActionGet && [[args objectAtIndex:2] 
isEqualToString:FORMAT_OPTION_STRING]) {
-            if (argc < 5) {
-                WRITE_ERROR;
-                [pool release];
-                exit(EXIT_FAILURE);
-            }
-            offset = 4;
-            format = SKNFormatForString([args objectAtIndex:3]);
-        } else if ((action == SKNActionSet || action == SKNActionConvert || 
action == SKNActionTest) && ([[args objectAtIndex:2] 
isEqualToString:SYNCABLE_OPTION_STRING] || [[args objectAtIndex:2] 
isEqualToString:NONSYNCABLE_OPTION_STRING])) {
-            if (argc < 4) {
-                WRITE_ERROR;
-                [pool release];
-                exit(EXIT_FAILURE);
-            }
-            syncable = [[args objectAtIndex:2] 
isEqualToString:SYNCABLE_OPTION_STRING] ? SKNSyncable : SKNNonSyncable;
-            offset = 3;
-        } else if (action == SKNActionFormat) {
-            if (argc < 4) {
-                WRITE_ERROR;
-                [pool release];
-                exit(EXIT_FAILURE);
-            }
-            offset = 3;
-            format = SKNFormatForString([args objectAtIndex:2]);
-        } else if (action == SKNActionOffset) {
-            if (argc < 5) {
-                WRITE_ERROR;
-                [pool release];
-                exit(EXIT_FAILURE);
-            }
-            offset = 4;
-            dx = [[args objectAtIndex:2] doubleValue];
-            dy = [[args objectAtIndex:3] doubleValue];
-        }
-        
-        NSFileManager *fm = [NSFileManager defaultManager];
-        NSString *inPath = SKNNormalizedPath([args objectAtIndex:offset]);
-        NSString *outPath = argc < offset + 2 ? nil : SKNNormalizedPath([args 
objectAtIndex:offset + 1]);
-        BOOL isBundle = NO;
-        BOOL isDir = NO;
-        BOOL isStdIn = NO;
-        NSError *error = nil;
-        
-        if (action == SKNActionOffset || action == SKNActionFormat) {
-            if ([inPath isEqualToString:STD_IN_OUT_FILE])
-                isStdIn = YES;
-            else if ([[inPath pathExtension] 
caseInsensitiveCompare:SKIM_EXTENSION] != NSOrderedSame)
-                inPath = [[inPath stringByDeletingPathExtension] 
stringByAppendingPathExtension:SKIM_EXTENSION];
-        } else if ([[inPath pathExtension] 
caseInsensitiveCompare:PDFD_EXTENSION] == NSOrderedSame) {
-            isBundle = YES;
-        } else if ([[inPath pathExtension] 
caseInsensitiveCompare:PDF_EXTENSION] != NSOrderedSame) {
-            inPath = [[inPath stringByDeletingPathExtension] 
stringByAppendingPathExtension:PDF_EXTENSION];
-        }
-        
-        if (action != SKNActionRemove && action != SKNActionTest && outPath == 
nil) {
-            outPath = [inPath stringByDeletingPathExtension];
-            if (action == SKNActionConvert)
-                outPath = [outPath stringByAppendingPathExtension:isBundle ? 
PDF_EXTENSION : PDFD_EXTENSION];
-            else if (action == SKNActionOffset)
-                outPath = inPath;
-            else if ([outPath isEqualToString:STD_IN_OUT_FILE] == NO)
-                outPath = [outPath stringByAppendingPathExtension:format == 
SKNFormatText ? TXT_EXTENSION : format == SKNFormatRTF ? RTF_EXTENSION : 
SKIM_EXTENSION];
-        }
-        
-        if (((action != SKNActionOffset && action != SKNActionFormat) || 
isStdIn == NO) && ([fm fileExistsAtPath:inPath isDirectory:&isDir] == NO || 
isBundle != isDir)) {
+        if (action == SKNActionUnknown) {
             
-            error = [NSError errorWithDomain:NSPOSIXErrorDomain code:ENOENT 
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:(action == SKNActionOffset 
|| action == SKNActionFormat) ? @"Skim file does not exist" : isBundle ? @"PDF 
bundle does not exist" : @"PDF file does not exist", NSLocalizedDescriptionKey, 
nil]];
+            WRITE_ERROR;
+            exit(EXIT_FAILURE);
             
-        } else if (action == SKNActionGet) {
+        } else if (action == SKNActionAgent) {
             
-            NSData *data = nil;
-            if (format == SKNFormatAuto) {
-                NSString *extension = [outPath pathExtension];
-                if ([extension caseInsensitiveCompare:RTF_EXTENSION] == 
NSOrderedSame)
-                    format = SKNFormatRTF;
-                else if ([extension caseInsensitiveCompare:TXT_EXTENSION] == 
NSOrderedSame || [extension caseInsensitiveCompare:TEXT_EXTENSION] == 
NSOrderedSame)
-                    format = SKNFormatText;
-                else
-                    format = SKNFormatSkim;
-            }
-            if (format == SKNFormatSkim) {
-                data = [fm SkimNotesAtPath:inPath error:&error];
-            } else if (format == SKNFormatText) {
-                data = [[fm SkimTextNotesAtPath:inPath error:&error] 
dataUsingEncoding:NSUTF8StringEncoding];
-            } else if (format == SKNFormatRTF) {
-                data = [fm SkimRTFNotesAtPath:inPath error:&error];
-            } else if (format == SKNFormatArchive || format == SKNFormatPlist) 
{
-                data = [fm SkimNotesAtPath:inPath error:&error];
-                BOOL hasEncoding = NO;
-                if ([data length] > 8) {
-                    char bytes[100];
-                    [data getBytes:bytes range:NSMakeRange(0, format == 
SKNFormatPlist ? 9 : MIN(100, [data length]))];
-                    if (strncmp(bytes, "bplist00", 8) != 0) {
-                        unsigned char marker = (unsigned char)bytes[8] >> 4;
-                        hasEncoding = format == SKNFormatPlist ? (marker == 
0xA) : (marker == 0xD && strstr(bytes, "$archiver") != NULL);
-                    }
+            BOOL isXPC = ([args count] > 2 && [[args objectAtIndex:2] 
isEqualToString:XPC_OPTION_STRING]);
+            NSString *serverName = [args count] > (isXPC ? 3 : 2) ? [args 
lastObject] : nil;
+            
+            SKNAgentListener *listener = [[SKNAgentListener alloc] 
initWithServerName:serverName xpc:isXPC];
+            
+            NSRunLoop *rl = [NSRunLoop currentRunLoop];
+            BOOL didRun;
+            
+            do {
+                @autoreleasepool {
+                    didRun = [rl runMode:NSDefaultRunLoopMode 
beforeDate:[NSDate distantFuture]];
                 }
-                if (hasEncoding == NO)
-                    data = SKNDataFromSkimNotes(SKNSkimNotesFromData(data), 
format == SKNFormatPlist);
-            }
-            if (data) {
-                if ([outPath isEqualToString:STD_IN_OUT_FILE]) {
-                    if ([data length])
-                        [(NSFileHandle *)[NSFileHandle 
fileHandleWithStandardOutput] writeData:data];
-                    success = YES;
-                } else {
-                    if ([data length]) {
-                        success = [data writeToFile:outPath 
options:NSAtomicWrite error:&error];
-                    } else if ([fm fileExistsAtPath:outPath 
isDirectory:&isDir] && isDir == NO) {
-                        success = [fm removeItemAtPath:outPath error:NULL];
-                        if (success == NO)
-                            error = [NSError 
errorWithDomain:NSPOSIXErrorDomain code:EACCES userInfo:[NSDictionary 
dictionaryWithObjectsAndKeys:@"Unable to remove file", 
NSLocalizedDescriptionKey, nil]];
-                    } else {
-                        success = YES;
-                    }
-                }
-            }
+            } while (listener && didRun);
             
-        } else if (action == SKNActionSet) {
+            success = YES;
             
-            if (outPath && ([outPath isEqualToString:STD_IN_OUT_FILE] || ([fm 
fileExistsAtPath:outPath isDirectory:&isDir] && isDir == NO))) {
-                NSData *data = nil;
-                NSString *textString = nil;
-                NSData *rtfData = nil;
-                if ([outPath isEqualToString:STD_IN_OUT_FILE])
-                    data = [[NSFileHandle fileHandleWithStandardInput] 
readDataToEndOfFile];
-                else
-                    data = [NSData dataWithContentsOfFile:outPath];
-                if (argc > offset + 2) {
-                    NSString *outPath2 = SKNNormalizedPath([args 
objectAtIndex:offset + 2]);
-                    NSString *outPath3 = argc < offset + 4 ? nil : 
SKNNormalizedPath([args objectAtIndex:offset + 3]);
-                    if ([[outPath2 pathExtension] 
caseInsensitiveCompare:TXT_EXTENSION] == NSOrderedSame || [[outPath2 
pathExtension] caseInsensitiveCompare:TEXT_EXTENSION] == NSOrderedSame)
-                        textString = [NSString 
stringWithContentsOfFile:outPath2 encoding:NSUTF8StringEncoding error:NULL];
-                    else if ([[outPath3 pathExtension] 
caseInsensitiveCompare:TXT_EXTENSION] == NSOrderedSame || [[outPath3 
pathExtension] caseInsensitiveCompare:TEXT_EXTENSION] == NSOrderedSame)
-                        textString = [NSString 
stringWithContentsOfFile:outPath3 encoding:NSUTF8StringEncoding error:NULL];
-                    if ([[outPath3 pathExtension] 
caseInsensitiveCompare:RTF_EXTENSION] == NSOrderedSame)
-                        rtfData = [NSData dataWithContentsOfFile:outPath3];
-                    else if ([[outPath2 pathExtension] 
caseInsensitiveCompare:RTF_EXTENSION] == NSOrderedSame)
-                        rtfData = [NSData dataWithContentsOfFile:outPath2];
-                }
-                if ([data length])
-                    success = [fm writeSkimNotes:data textNotes:textString 
RTFNotes:rtfData atPath:inPath syncable:syncable != SKNNonSyncable 
error:&error];
-                else if (data)
-                    success = [fm removeSkimNotesAtPath:inPath error:&error];
+        } else if (action == SKNActionProtocol) {
+            
+            if ([args count] > 2 && [[args objectAtIndex:2] 
isEqualToString:XPC_OPTION_STRING]) {
+                WRITE_OUT(xpcProtocolStr);
             } else {
-                error = [NSError errorWithDomain:NSPOSIXErrorDomain 
code:ENOENT userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Notes file 
does not exist", NSLocalizedDescriptionKey, nil]];
+                WRITE_OUT(protocolStr);
             }
+            success = YES;
             
-        } else if (action == SKNActionRemove) {
+        } else if (action == SKNActionHelp) {
             
-            success = [fm removeSkimNotesAtPath:inPath error:&error];
+            NSInteger helpAction = SKNActionForName([args count] > 2 ? [args 
objectAtIndex:2] : @"");
             
-        } else if (action == SKNActionTest) {
+            switch (helpAction) {
+                case SKNActionUnknown:
+                    WRITE_OUT_VERSION(usageStr);
+                    break;
+                case SKNActionGet:
+                    WRITE_OUT(getHelpStr);
+                    break;
+                case SKNActionSet:
+                    WRITE_OUT(setHelpStr);
+                    break;
+                case SKNActionRemove:
+                    WRITE_OUT(removeHelpStr);
+                    break;
+                case SKNActionTest:
+                    WRITE_OUT(testHelpStr);
+                    break;
+                case SKNActionConvert:
+                    WRITE_OUT(convertHelpStr);
+                    break;
+                case SKNActionFormat:
+                    WRITE_OUT(formatHelpStr);
+                    break;
+                case SKNActionOffset:
+                    WRITE_OUT(offsetHelpStr);
+                    break;
+                case SKNActionAgent:
+                    WRITE_OUT(agentHelpStr);
+                    break;
+                case SKNActionProtocol:
+                    WRITE_OUT(protocolHelpStr);
+                    break;
+                case SKNActionVersion:
+                    WRITE_OUT(versionHelpStr);
+                    break;
+                case SKNActionHelp:
+                    WRITE_OUT(helpHelpStr);
+                    break;
+            }
+            success = YES;
             
-            success = [fm hasSkimNotesAtPath:inPath syncable:syncable];
+        } else if (action == SKNActionVersion) {
             
-        } else if (action == SKNActionConvert) {
+            WRITE_OUT(versionStr);
+            success = YES;
             
-            if (isBundle) {
-                NSString *pdfFilePath = nil;
-                NSArray *files = [fm subpathsAtPath:inPath];
-                NSString *filename = [[[inPath lastPathComponent] 
stringByDeletingPathExtension] stringByAppendingPathExtension:PDF_EXTENSION];
-                if ([files containsObject:filename] == NO) {
-                    NSUInteger idx = [[files 
valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:PDF_EXTENSION];
-                    filename = idx == NSNotFound ? nil : [files 
objectAtIndex:idx];
+        } else {
+            
+            if (argc < 3) {
+                WRITE_ERROR;
+                exit(EXIT_FAILURE);
+            }
+            
+            NSInteger format = SKNFormatAuto;
+            CGFloat dx = 0.0, dy = 0.0;
+            SKNSyncability syncable = SKNAnySyncable;
+            int offset = 2;
+            
+            if (action == SKNActionGet && [[args objectAtIndex:2] 
isEqualToString:FORMAT_OPTION_STRING]) {
+                if (argc < 5) {
+                    WRITE_ERROR;
+                    exit(EXIT_FAILURE);
                 }
-                if (filename)
-                    pdfFilePath = [inPath 
stringByAppendingPathComponent:filename];
-                success = [fm copyItemAtPath:pdfFilePath toPath:outPath 
error:NULL];
-            } else if ([[outPath pathExtension] 
caseInsensitiveCompare:PDFD_EXTENSION] == NSOrderedSame) {
-                success = [fm createDirectoryAtPath:outPath 
withIntermediateDirectories:NO attributes:nil error:NULL];
-                if (success) {
-                    NSString *pdfFilePath = [outPath 
stringByAppendingPathComponent:[[[outPath lastPathComponent] 
stringByDeletingPathExtension] stringByAppendingPathExtension:PDF_EXTENSION]];
-                    success = [[NSData dataWithContentsOfFile:inPath options:0 
error:&error] writeToFile:pdfFilePath options:0 error:&error];
+                offset = 4;
+                format = SKNFormatForString([args objectAtIndex:3]);
+            } else if ((action == SKNActionSet || action == SKNActionConvert 
|| action == SKNActionTest) && ([[args objectAtIndex:2] 
isEqualToString:SYNCABLE_OPTION_STRING] || [[args objectAtIndex:2] 
isEqualToString:NONSYNCABLE_OPTION_STRING])) {
+                if (argc < 4) {
+                    WRITE_ERROR;
+                    exit(EXIT_FAILURE);
                 }
-            } else if ([inPath isEqualToString:outPath]) {
-                success = YES;
-            } else {
-                success = [fm copyItemAtPath:inPath toPath:outPath error:NULL];
+                syncable = [[args objectAtIndex:2] 
isEqualToString:SYNCABLE_OPTION_STRING] ? SKNSyncable : SKNNonSyncable;
+                offset = 3;
+            } else if (action == SKNActionFormat) {
+                if (argc < 4) {
+                    WRITE_ERROR;
+                    exit(EXIT_FAILURE);
+                }
+                offset = 3;
+                format = SKNFormatForString([args objectAtIndex:2]);
+            } else if (action == SKNActionOffset) {
+                if (argc < 5) {
+                    WRITE_ERROR;
+                    exit(EXIT_FAILURE);
+                }
+                offset = 4;
+                dx = [[args objectAtIndex:2] doubleValue];
+                dy = [[args objectAtIndex:3] doubleValue];
             }
-            if (success) {
-                NSData *notesData = [fm SkimNotesAtPath:inPath error:&error];
-                NSString *textNotes = [fm SkimTextNotesAtPath:inPath 
error:&error];
-                NSData *rtfNotesData = [fm SkimRTFNotesAtPath:inPath 
error:&error];
-                if (notesData)
-                    success = [fm writeSkimNotes:notesData textNotes:textNotes 
RTFNotes:rtfNotesData atPath:outPath syncable:syncable != SKNNonSyncable 
error:&error];
+            
+            NSFileManager *fm = [NSFileManager defaultManager];
+            NSString *inPath = SKNNormalizedPath([args objectAtIndex:offset]);
+            NSString *outPath = argc < offset + 2 ? nil : 
SKNNormalizedPath([args objectAtIndex:offset + 1]);
+            BOOL isBundle = NO;
+            BOOL isDir = NO;
+            BOOL isStdIn = NO;
+            NSError *error = nil;
+            
+            if (action == SKNActionOffset || action == SKNActionFormat) {
+                if ([inPath isEqualToString:STD_IN_OUT_FILE])
+                    isStdIn = YES;
+                else if ([[inPath pathExtension] 
caseInsensitiveCompare:SKIM_EXTENSION] != NSOrderedSame)
+                    inPath = [[inPath stringByDeletingPathExtension] 
stringByAppendingPathExtension:SKIM_EXTENSION];
+            } else if ([[inPath pathExtension] 
caseInsensitiveCompare:PDFD_EXTENSION] == NSOrderedSame) {
+                isBundle = YES;
+            } else if ([[inPath pathExtension] 
caseInsensitiveCompare:PDF_EXTENSION] != NSOrderedSame) {
+                inPath = [[inPath stringByDeletingPathExtension] 
stringByAppendingPathExtension:PDF_EXTENSION];
             }
             
-        } else if (action == SKNActionFormat) {
+            if (action != SKNActionRemove && action != SKNActionTest && 
outPath == nil) {
+                outPath = [inPath stringByDeletingPathExtension];
+                if (action == SKNActionConvert)
+                    outPath = [outPath stringByAppendingPathExtension:isBundle 
? PDF_EXTENSION : PDFD_EXTENSION];
+                else if (action == SKNActionOffset)
+                    outPath = inPath;
+                else if ([outPath isEqualToString:STD_IN_OUT_FILE] == NO)
+                    outPath = [outPath stringByAppendingPathExtension:format 
== SKNFormatText ? TXT_EXTENSION : format == SKNFormatRTF ? RTF_EXTENSION : 
SKIM_EXTENSION];
+            }
             
-            NSData *data;
-            if (isStdIn)
-                data = [(NSFileHandle *)[NSFileHandle 
fileHandleWithStandardInput] readDataToEndOfFile];
-            else
-                data = [NSData dataWithContentsOfFile:inPath];
-            if (format == SKNFormatText) {
-                data = [SKNSkimTextNotes(SKNSkimNotesFromData(data)) 
dataUsingEncoding:NSUTF8StringEncoding];
-            } else if (format == SKNFormatRTF) {
-                data = SKNSkimRTFNotes(SKNSkimNotesFromData(data));
-            } else if (format == SKNFormatArchive || format == SKNFormatPlist) 
{
-                BOOL hasEncoding = NO;
-                if ([data length] > 8) {
-                    char bytes[100];
-                    [data getBytes:bytes range:NSMakeRange(0, format == 
SKNFormatPlist ? 9 : MIN(100, [data length]))];
-                    if (strncmp(bytes, "bplist00", 8) != 0) {
-                        unsigned char marker = (unsigned char)bytes[8] >> 4;
-                        hasEncoding = format == SKNFormatPlist ? (marker == 
0xA) : (marker == 0xD && strstr(bytes, "$archiver") != NULL);
+            if (((action != SKNActionOffset && action != SKNActionFormat) || 
isStdIn == NO) && ([fm fileExistsAtPath:inPath isDirectory:&isDir] == NO || 
isBundle != isDir)) {
+                
+                error = [NSError errorWithDomain:NSPOSIXErrorDomain 
code:ENOENT userInfo:[NSDictionary dictionaryWithObjectsAndKeys:(action == 
SKNActionOffset || action == SKNActionFormat) ? @"Skim file does not exist" : 
isBundle ? @"PDF bundle does not exist" : @"PDF file does not exist", 
NSLocalizedDescriptionKey, nil]];
+                
+            } else if (action == SKNActionGet) {
+                
+                NSData *data = nil;
+                if (format == SKNFormatAuto) {
+                    NSString *extension = [outPath pathExtension];
+                    if ([extension caseInsensitiveCompare:RTF_EXTENSION] == 
NSOrderedSame)
+                        format = SKNFormatRTF;
+                    else if ([extension caseInsensitiveCompare:TXT_EXTENSION] 
== NSOrderedSame || [extension caseInsensitiveCompare:TEXT_EXTENSION] == 
NSOrderedSame)
+                        format = SKNFormatText;
+                    else
+                        format = SKNFormatSkim;
+                }
+                if (format == SKNFormatSkim) {
+                    data = [fm SkimNotesAtPath:inPath error:&error];
+                } else if (format == SKNFormatText) {
+                    data = [[fm SkimTextNotesAtPath:inPath error:&error] 
dataUsingEncoding:NSUTF8StringEncoding];
+                } else if (format == SKNFormatRTF) {
+                    data = [fm SkimRTFNotesAtPath:inPath error:&error];
+                } else if (format == SKNFormatArchive || format == 
SKNFormatPlist) {
+                    data = [fm SkimNotesAtPath:inPath error:&error];
+                    BOOL hasEncoding = NO;
+                    if ([data length] > 8) {
+                        char bytes[100];
+                        [data getBytes:bytes range:NSMakeRange(0, format == 
SKNFormatPlist ? 9 : MIN(100, [data length]))];
+                        if (strncmp(bytes, "bplist00", 8) != 0) {
+                            unsigned char marker = (unsigned char)bytes[8] >> 
4;
+                            hasEncoding = format == SKNFormatPlist ? (marker 
== 0xA) : (marker == 0xD && strstr(bytes, "$archiver") != NULL);
+                        }
                     }
+                    if (hasEncoding == NO)
+                        data = 
SKNDataFromSkimNotes(SKNSkimNotesFromData(data), format == SKNFormatPlist);
                 }
-                if (hasEncoding == NO)
-                    data = SKNDataFromSkimNotes(SKNSkimNotesFromData(data), 
format == SKNFormatPlist);
-            }
-            if (data) {
-                if ([outPath isEqualToString:STD_IN_OUT_FILE]) {
-                    [(NSFileHandle *)[NSFileHandle 
fileHandleWithStandardOutput] writeData:data];
+                if (data) {
+                    if ([outPath isEqualToString:STD_IN_OUT_FILE]) {
+                        if ([data length])
+                            [(NSFileHandle *)[NSFileHandle 
fileHandleWithStandardOutput] writeData:data];
+                        success = YES;
+                    } else {
+                        if ([data length]) {
+                            success = [data writeToFile:outPath 
options:NSAtomicWrite error:&error];
+                        } else if ([fm fileExistsAtPath:outPath 
isDirectory:&isDir] && isDir == NO) {
+                            success = [fm removeItemAtPath:outPath error:NULL];
+                            if (success == NO)
+                                error = [NSError 
errorWithDomain:NSPOSIXErrorDomain code:EACCES userInfo:[NSDictionary 
dictionaryWithObjectsAndKeys:@"Unable to remove file", 
NSLocalizedDescriptionKey, nil]];
+                        } else {
+                            success = YES;
+                        }
+                    }
+                }
+                
+            } else if (action == SKNActionSet) {
+                
+                if (outPath && ([outPath isEqualToString:STD_IN_OUT_FILE] || 
([fm fileExistsAtPath:outPath isDirectory:&isDir] && isDir == NO))) {
+                    NSData *data = nil;
+                    NSString *textString = nil;
+                    NSData *rtfData = nil;
+                    if ([outPath isEqualToString:STD_IN_OUT_FILE])
+                        data = [[NSFileHandle fileHandleWithStandardInput] 
readDataToEndOfFile];
+                    else
+                        data = [NSData dataWithContentsOfFile:outPath];
+                    if (argc > offset + 2) {
+                        NSString *outPath2 = SKNNormalizedPath([args 
objectAtIndex:offset + 2]);
+                        NSString *outPath3 = argc < offset + 4 ? nil : 
SKNNormalizedPath([args objectAtIndex:offset + 3]);
+                        if ([[outPath2 pathExtension] 
caseInsensitiveCompare:TXT_EXTENSION] == NSOrderedSame || [[outPath2 
pathExtension] caseInsensitiveCompare:TEXT_EXTENSION] == NSOrderedSame)
+                            textString = [NSString 
stringWithContentsOfFile:outPath2 encoding:NSUTF8StringEncoding error:NULL];
+                        else if ([[outPath3 pathExtension] 
caseInsensitiveCompare:TXT_EXTENSION] == NSOrderedSame || [[outPath3 
pathExtension] caseInsensitiveCompare:TEXT_EXTENSION] == NSOrderedSame)
+                            textString = [NSString 
stringWithContentsOfFile:outPath3 encoding:NSUTF8StringEncoding error:NULL];
+                        if ([[outPath3 pathExtension] 
caseInsensitiveCompare:RTF_EXTENSION] == NSOrderedSame)
+                            rtfData = [NSData dataWithContentsOfFile:outPath3];

@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to