Revision: 4241
http://skim-app.svn.sourceforge.net/skim-app/?rev=4241&view=rev
Author: hofman
Date: 2008-07-17 19:02:39 +0000 (Thu, 17 Jul 2008)
Log Message:
-----------
Add a fileManager category for the tool to consolidate read/write code of skim
notes for several file types. Allow passing a PDF bundle instead of a PDF file
to the tool. Add an action to convert a PDF file to a PDF bundle and vv.
Modified Paths:
--------------
trunk/SkimNotes/NSFileManager_SKNExtensions.m
trunk/SkimNotes/SKNAgentListener.m
trunk/SkimNotes/SkimNotes.xcodeproj/project.pbxproj
trunk/SkimNotes/skimnotes.m
Added Paths:
-----------
trunk/SkimNotes/NSFileManager_SKNToolExtensions.h
trunk/SkimNotes/NSFileManager_SKNToolExtensions.m
trunk/SkimNotes/SKNUtilities.h
trunk/SkimNotes/SKNUtilities.m
Modified: trunk/SkimNotes/NSFileManager_SKNExtensions.m
===================================================================
--- trunk/SkimNotes/NSFileManager_SKNExtensions.m 2008-07-17 17:04:15 UTC
(rev 4240)
+++ trunk/SkimNotes/NSFileManager_SKNExtensions.m 2008-07-17 19:02:39 UTC
(rev 4241)
@@ -38,74 +38,10 @@
#import "NSFileManager_SKNExtensions.h"
#import "SKNExtendedAttributeManager.h"
+#import "SKNUtilities.h"
-#define SKIM_NOTES_KEY @"net_sourceforge_skim-app_notes"
-#define SKIM_RTF_NOTES_KEY @"net_sourceforge_skim-app_rtf_notes"
-#define SKIM_TEXT_NOTES_KEY @"net_sourceforge_skim-app_text_notes"
-
-#define NOTE_PAGE_INDEX_KEY @"pageIndex"
-#define NOTE_TYPE_KEY @"type"
-#define NOTE_CONTENTS_KEY @"contents"
-#define NOTE_TEXT_KEY @"text"
-
@implementation NSFileManager (SKNExtensions)
-static NSString *SKNTextNotes(NSArray *noteDicts) {
- NSMutableString *textString = [NSMutableString string];
- NSEnumerator *dictEnum = [noteDicts objectEnumerator];
- NSDictionary *dict;
-
- while (dict = [dictEnum nextObject]) {
- NSString *type = [dict objectForKey:NOTE_TYPE_KEY];
- NSUInteger pageIndex = [[dict objectForKey:NOTE_PAGE_INDEX_KEY]
unsignedIntValue];
- NSString *string = [dict objectForKey:NOTE_CONTENTS_KEY];
- NSAttributedString *text = [dict objectForKey:NOTE_TEXT_KEY];
-
- if (pageIndex == NSNotFound || pageIndex == UINT_MAX)
- pageIndex = 0;
-
- [textString appendFormat:@"* %@, page %lu\n\n", type, (long)pageIndex
+ 1];
- if ([string length]) {
- [textString appendString:string];
- [textString appendString:@" \n\n"];
- }
- if ([text length]) {
- [textString appendString:[text string]];
- [textString appendString:@" \n\n"];
- }
- }
- return textString;
-}
-
-static NSAttributedString *SKNRichTextNotes(NSArray *noteDicts) {
- NSMutableAttributedString *attrString = [[[NSMutableAttributedString
alloc] init] autorelease];
- NSEnumerator *dictEnum = [noteDicts objectEnumerator];
- NSDictionary *dict;
-
- while (dict = [dictEnum nextObject]) {
- NSString *type = [dict objectForKey:NOTE_TYPE_KEY];
- NSUInteger pageIndex = [[dict objectForKey:NOTE_PAGE_INDEX_KEY]
unsignedIntValue];
- NSString *string = [dict objectForKey:NOTE_CONTENTS_KEY];
- NSAttributedString *text = [dict objectForKey:NOTE_TEXT_KEY];
-
- if (pageIndex == NSNotFound || pageIndex == UINT_MAX)
- pageIndex = 0;
-
- [attrString replaceCharactersInRange:NSMakeRange([attrString length],
0) withString:[NSString stringWithFormat:@"* %@, page %lu\n\n", type,
(long)pageIndex + 1]];
- if ([string length]) {
- [attrString replaceCharactersInRange:NSMakeRange([attrString
length], 0) withString:string];
- [attrString replaceCharactersInRange:NSMakeRange([attrString
length], 0) withString:@" \n\n"];
- }
- if ([text length]) {
- [attrString appendAttributedString:text];
- [attrString replaceCharactersInRange:NSMakeRange([attrString
length], 0) withString:@" \n\n"];
-
- }
- }
- [attrString fixAttributesInRange:NSMakeRange(0, [attrString length])];
- return attrString;
-}
-
- (BOOL)writeSkimNotes:(NSArray *)notes toExtendedAttributesAtURL:(NSURL
*)aURL error:(NSError **)outError {
return [self writeSkimNotes:notes textNotes:nil richTextNotes:nil
toExtendedAttributesAtURL:aURL error:outError];
}
@@ -135,10 +71,8 @@
} else {
if (notesString == nil)
notesString = SKNTextNotes(notes);
- if (notesRTFData == nil) {
- NSAttributedString *notesAttrString =
SKNRichTextNotes(notes);
- notesRTFData = [notesAttrString
RTFFromRange:NSMakeRange(0, [notesAttrString length]) documentAttributes:nil];
- }
+ if (notesRTFData == nil)
+ notesRTFData = SKNRTFNotes(notes);
[eam setExtendedAttributeNamed:SKIM_TEXT_NOTES_KEY
toPropertyListValue:notesString atPath:path options:0 error:NULL];
[eam setExtendedAttributeNamed:SKIM_RTF_NOTES_KEY
toValue:notesRTFData atPath:path options:0 error:NULL];
}
Added: trunk/SkimNotes/NSFileManager_SKNToolExtensions.h
===================================================================
--- trunk/SkimNotes/NSFileManager_SKNToolExtensions.h
(rev 0)
+++ trunk/SkimNotes/NSFileManager_SKNToolExtensions.h 2008-07-17 19:02:39 UTC
(rev 4241)
@@ -0,0 +1,52 @@
+//
+// NSFileManager_SKNToolExtensions.h
+// SkimNotes
+//
+// Created by Christiaan Hofman on 7/17/08.
+/*
+ This software is Copyright (c) 2008
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
[EMAIL PROTECTED] NSFileManager (SKNToolExtensions)
+
+- (NSData *)SkimNotesAtPath:(NSString *)path error:(NSError **)outError;
+- (NSString *)SkimTextNotesAtPath:(NSString *)path error:(NSError **)outError;
+- (NSData *)SkimRTFNotesAtPath:(NSString *)path error:(NSError **)outError;
+
+- (BOOL)writeSkimNotes:(NSData *)notesData textNotes:(NSString *)textNotes
RTFNotes:(NSData *)rtfNotesData atPath:(NSString *)path error:(NSError
**)outError;
+
+- (BOOL)removeSkimNotesAtPath:(NSString *)path error:(NSError **)outError;
+
[EMAIL PROTECTED]
Added: trunk/SkimNotes/NSFileManager_SKNToolExtensions.m
===================================================================
--- trunk/SkimNotes/NSFileManager_SKNToolExtensions.m
(rev 0)
+++ trunk/SkimNotes/NSFileManager_SKNToolExtensions.m 2008-07-17 19:02:39 UTC
(rev 4241)
@@ -0,0 +1,231 @@
+//
+// NSFileManager_SKNToolExtensions.m
+// SkimNotes
+//
+// Created by Christiaan Hofman on 7/17/08.
+/*
+ This software is Copyright (c) 2008
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "NSFileManager_SKNToolExtensions.h"
+#import "SKNExtendedAttributeManager.h"
+#import "SKNUtilities.h"
+
+#define PDFD_EXTENSION @"pdfd"
+#define SKIM_EXTENSION @"skim"
+#define TXT_EXTENSION @"txt"
+#define RTF_EXTENSION @"rtf"
+
+#define BUNDLE_DATA_FILENAME @"data"
+
[EMAIL PROTECTED] NSFileManager (SKNToolExtensions)
+
+- (NSString *)notesFileWithExtension:(NSString *)extension atPath:(NSString
*)path error:(NSError **)error {
+ NSString *filePath = nil;
+
+ path = [path stringByStandardizingPath];
+ if ([extension caseInsensitiveCompare:SKIM_EXTENSION] == NSOrderedSame) {
+ NSArray *files = [self subpathsAtPath:path];
+ NSString *filename = [[[path lastPathComponent]
stringByDeletingPathExtension] stringByAppendingPathExtension:SKIM_EXTENSION];
+ if ([files containsObject:filename] == NO) {
+ NSUInteger idx = [[files
valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:SKIM_EXTENSION];
+ filename = idx == NSNotFound ? nil : [files objectAtIndex:idx];
+ }
+ if (filename)
+ filePath = [path stringByAppendingPathComponent:filename];
+ } else {
+ NSString *skimFile = [self notesFileWithExtension:SKIM_EXTENSION
atPath:path error:error];
+ if (skimFile) {
+ filePath = [[skimFile stringByDeletingPathExtension]
stringByAppendingPathExtension:extension];
+ if ([[NSFileManager defaultManager] fileExistsAtPath:filePath] ==
NO)
+ filePath = nil;
+ }
+ }
+ if (filePath == nil && error)
+ *error = [NSError errorWithDomain:NSPOSIXErrorDomain code:ENOENT
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Notes file note found",
NSLocalizedDescriptionKey, nil]];
+ return filePath;
+}
+
+- (NSData *)SkimNotesAtPath:(NSString *)path error:(NSError **)outError {
+ NSError *error;
+ NSData *data = nil;
+ NSString *extension = [path pathExtension];
+
+ path = [path stringByStandardizingPath];
+ if ([extension caseInsensitiveCompare:PDFD_EXTENSION] == NSOrderedSame) {
+ NSString *notePath = [self notesFileWithExtension:SKIM_EXTENSION
atPath:path error:&error];
+ if (notePath)
+ data = [NSData dataWithContentsOfFile:notePath options:0
error:&error];
+ if (nil == data && outError)
+ *outError = error;
+ } else if ([extension caseInsensitiveCompare:SKIM_EXTENSION] ==
NSOrderedSame) {
+ data = [NSData dataWithContentsOfFile:path options:0 error:&error];
+ if (nil == data && outError)
+ *outError = error;
+ } else {
+ data = [[SKNExtendedAttributeManager sharedManager]
extendedAttributeNamed:SKIM_NOTES_KEY atPath:path traverseLink:YES
error:&error];
+ if (nil == data) {
+ if ([error code] != ENOATTR)
+ data = [NSData data];
+ else if (outError)
+ *outError = error;
+ }
+ }
+ return data;
+}
+
+- (NSString *)SkimTextNotesAtPath:(NSString *)path error:(NSError **)outError {
+ NSError *error;
+ NSString *string = nil;
+ NSString *extension = [path pathExtension];
+
+ path = [path stringByStandardizingPath];
+ if ([extension caseInsensitiveCompare:PDFD_EXTENSION] == NSOrderedSame) {
+ NSString *notePath = [self notesFileWithExtension:TXT_EXTENSION
atPath:path error:&error];
+ if (notePath)
+ string = [NSString stringWithContentsOfFile:notePath
encoding:NSUTF8StringEncoding error:&error];
+ if (nil == string && outError)
+ *outError = error;
+ } else {
+ string = [[SKNExtendedAttributeManager sharedManager]
propertyListFromExtendedAttributeNamed:SKIM_TEXT_NOTES_KEY atPath:path
traverseLink:YES error:&error];
+ if (nil == string) {
+ if ([error code] != ENOATTR)
+ string = @"";
+ else if (outError)
+ *outError = error;
+ }
+ }
+ return string;
+}
+
+- (NSData *)SkimRTFNotesAtPath:(NSString *)path error:(NSError **)outError {
+ NSError *error;
+ NSData *data = nil;
+ NSString *extension = [path pathExtension];
+
+ path = [path stringByStandardizingPath];
+ if ([extension caseInsensitiveCompare:PDFD_EXTENSION] == NSOrderedSame) {
+ NSString *notePath = [self notesFileWithExtension:RTF_EXTENSION
atPath:path error:&error];
+ if (notePath)
+ data = [NSData dataWithContentsOfFile:notePath options:0
error:&error];
+ if (nil == data && outError)
+ *outError = error;
+ } else {
+ data = [[SKNExtendedAttributeManager sharedManager]
extendedAttributeNamed:SKIM_RTF_NOTES_KEY atPath:path traverseLink:YES
error:&error];
+ if (nil == data) {
+ if ([error code] != ENOATTR)
+ data = [NSData data];
+ else if (outError)
+ *outError = error;
+ }
+ }
+ return data;
+}
+
+- (BOOL)writeSkimNotes:(NSData *)notesData textNotes:(NSString *)textNotes
RTFNotes:(NSData *)rtfNotesData atPath:(NSString *)path error:(NSError
**)outError {
+ BOOL success = YES;
+ NSError *error = nil;
+ NSString *extension = [path pathExtension];
+
+ [self removeSkimNotesAtPath:path error:NULL];
+ if ([notesData length]) {
+ NSArray *notes = [NSKeyedUnarchiver unarchiveObjectWithData:notesData];
+ if ([notes count]) {
+ if (textNotes == nil)
+ textNotes = SKNTextNotes(notes);
+ if (rtfNotesData == nil)
+ rtfNotesData = SKNRTFNotes(notes);
+ }
+ NSData *textNotesData = [textNotes
dataUsingEncoding:NSUTF8StringEncoding];
+ if ([extension caseInsensitiveCompare:PDFD_EXTENSION] ==
NSOrderedSame) {
+ NSString *name = [[path lastPathComponent]
stringByDeletingPathExtension];
+ if ([name caseInsensitiveCompare:BUNDLE_DATA_FILENAME] ==
NSOrderedSame)
+ name = [name stringByAppendingString:@"1"];
+ NSString *notePath = [[path stringByAppendingPathComponent:name]
stringByAppendingPathExtension:SKIM_EXTENSION];
+ success = [notesData writeToFile:notePath options:0 error:&error];
+ if (textNotesData) {
+ notePath = [[path stringByAppendingPathComponent:name]
stringByAppendingPathExtension:TXT_EXTENSION];
+ [textNotesData writeToFile:notePath options:0 error:NULL];
+ }
+ if (rtfNotesData) {
+ notePath = [[path stringByAppendingPathComponent:name]
stringByAppendingPathExtension:TXT_EXTENSION];
+ [rtfNotesData writeToFile:notePath options:0 error:NULL];
+ }
+ } else {
+ SKNExtendedAttributeManager *eam = [SKNExtendedAttributeManager
sharedManager];
+ success = [eam setExtendedAttributeNamed:SKIM_NOTES_KEY
toValue:notesData atPath:path options:0 error:&error];
+ if (textNotesData)
+ [eam setExtendedAttributeNamed:SKIM_TEXT_NOTES_KEY
toValue:textNotesData atPath:path options:0 error:NULL];
+ if (rtfNotesData)
+ [eam setExtendedAttributeNamed:SKIM_RTF_NOTES_KEY
toValue:rtfNotesData atPath:path options:0 error:NULL];
+ }
+ }
+ return success;
+}
+
+- (BOOL)removeSkimNotesAtPath:(NSString *)path error:(NSError **)outError {
+ BOOL success1 = YES, success2 = YES, success3 = YES;
+ NSError *error1 = nil, *error2 = nil, *error3 = nil;
+ NSString *extension = [path pathExtension];
+
+ if ([extension caseInsensitiveCompare:PDFD_EXTENSION] == NSOrderedSame) {
+ NSString *notePath;
+ if (notePath = [self notesFileWithExtension:SKIM_EXTENSION atPath:path
error:NULL])
+ success1 = [self removeFileAtPath:notePath handler:nil];
+ if (notePath = [self notesFileWithExtension:TXT_EXTENSION atPath:path
error:NULL])
+ success2 = [self removeFileAtPath:notePath handler:nil];
+ if (notePath = [self notesFileWithExtension:RTF_EXTENSION atPath:path
error:NULL])
+ success3 = [self removeFileAtPath:notePath handler:nil];
+ if (success1 == NO || success2 == NO || success3 == NO)
+ error1 = error2 = error3 = [NSError
errorWithDomain:NSPOSIXErrorDomain code:ENOENT userInfo:[NSDictionary
dictionaryWithObjectsAndKeys:@"Could not remove notes file",
NSLocalizedDescriptionKey, nil]];
+ } else {
+ SKNExtendedAttributeManager *eam = [SKNExtendedAttributeManager
sharedManager];
+ success1 = [eam removeExtendedAttribute:SKIM_NOTES_KEY atPath:path
traverseLink:YES error:&error1];
+ if (success1 == NO && [error1 code] == ENOATTR)
+ success1 = YES;
+ success2 = [eam removeExtendedAttribute:SKIM_RTF_NOTES_KEY atPath:path
traverseLink:YES error:&error2];
+ if (success2 == NO && [error2 code] == ENOATTR)
+ success2 = YES;
+ success3 = [eam removeExtendedAttribute:SKIM_TEXT_NOTES_KEY
atPath:path traverseLink:YES error:&error3];
+ if (success3 == NO && [error3 code] == ENOATTR)
+ success3 = YES;
+ }
+ if (success1 == NO && outError)
+ *outError = error1;
+ else if (success2 == NO && outError)
+ *outError = error2;
+ else if (success3 == NO && outError)
+ *outError = error3;
+ return success1 && success2 && success3;
+}
+
[EMAIL PROTECTED]
Modified: trunk/SkimNotes/SKNAgentListener.m
===================================================================
--- trunk/SkimNotes/SKNAgentListener.m 2008-07-17 17:04:15 UTC (rev 4240)
+++ trunk/SkimNotes/SKNAgentListener.m 2008-07-17 19:02:39 UTC (rev 4241)
@@ -38,12 +38,8 @@
#import "SKNAgentListener.h"
#import "SKNAgentListenerProtocol.h"
#import <AppKit/AppKit.h>
-#import "SKNExtendedAttributeManager.h"
+#import "NSFileManager_SKNToolExtensions.h"
-#define SKIM_NOTES_KEY @"net_sourceforge_skim-app_notes"
-#define SKIM_RTF_NOTES_KEY @"net_sourceforge_skim-app_rtf_notes"
-#define SKIM_TEXT_NOTES_KEY @"net_sourceforge_skim-app_text_notes"
-
@implementation SKNAgentListener
- (id)initWithServerName:(NSString *)serverName;
@@ -79,92 +75,30 @@
[super dealloc];
}
-- (NSString *)notesFileWithExtension:(NSString *)extension atPath:(NSString
*)path error:(NSError **)error {
- NSString *filePath = nil;
-
- if ([extension caseInsensitiveCompare:@"skim"] == NSOrderedSame) {
- NSArray *files = [[NSFileManager defaultManager] subpathsAtPath:path];
- NSString *filename = [[[path lastPathComponent]
stringByDeletingPathExtension] stringByAppendingPathExtension:@"skim"];
- if ([files containsObject:filename] == NO) {
- NSUInteger idx = [[files
valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:@"skim"];
- filename = idx == NSNotFound ? nil : [files objectAtIndex:idx];
- }
- if (filename)
- filePath = [path stringByAppendingPathComponent:filename];
- } else {
- NSString *skimFile = [self notesFileWithExtension:@"skim" atPath:path
error:error];
- if (skimFile) {
- filePath = [[skimFile stringByDeletingPathExtension]
stringByAppendingPathExtension:extension];
- if ([[NSFileManager defaultManager] fileExistsAtPath:filePath] ==
NO)
- filePath = nil;
- }
- }
- if (filePath == nil && error)
- *error = [NSError errorWithDomain:NSPOSIXErrorDomain code:ENOENT
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Notes file note found",
NSLocalizedDescriptionKey, nil]];
- return filePath;
-}
-
- (bycopy NSData *)SkimNotesAtPath:(in bycopy NSString *)aFile;
{
- NSError *error;
- NSData *data = nil;
- NSString *extension = [[aFile pathExtension] lastPathComponent];
-
- if ([extension caseInsensitiveCompare:@"pdfd"] == NSOrderedSame) {
- NSString *notePath = [self notesFileWithExtension:@"skim" atPath:aFile
error:&error];
- if (notePath)
- data = [NSData dataWithContentsOfFile:notePath options:0
error:&error];
- if (nil == data)
- fprintf(stderr, "skimnotes agent pid %d: error getting Skim notes
(%s)\n", getpid(), [[error description] UTF8String]);
- } else if ([extension caseInsensitiveCompare:@"skim"] == NSOrderedSame) {
- data = [NSData dataWithContentsOfFile:aFile options:0 error:&error];
- if (nil == data)
- fprintf(stderr, "skimnotes agent pid %d: error getting Skim notes
(%s)\n", getpid(), [[error description] UTF8String]);
- } else {
- data = [[SKNExtendedAttributeManager sharedManager]
extendedAttributeNamed:SKIM_NOTES_KEY atPath:[aFile stringByStandardizingPath]
traverseLink:YES error:&error];
- if (nil == data && [error code] != ENOATTR)
- fprintf(stderr, "skimnotes agent pid %d: error getting Skim notes
(%s)\n", getpid(), [[error description] UTF8String]);
- }
+ NSError *error = nil;
+ NSData *data = [[NSFileManager defaultManager] SkimNotesAtPath:aFile
error:&error];
+ if (nil == data)
+ fprintf(stderr, "skimnotes agent pid %d: error getting Skim notes
(%s)\n", getpid(), [[error description] UTF8String]);
return data;
}
- (bycopy NSData *)RTFNotesAtPath:(in bycopy NSString *)aFile;
{
- NSError *error;
- NSData *data = nil;
- NSString *extension = [[aFile pathExtension] lastPathComponent];
-
- if ([extension caseInsensitiveCompare:@"pdfd"] == NSOrderedSame) {
- NSString *notePath = [self notesFileWithExtension:@"rtf" atPath:aFile
error:&error];
- if (notePath)
- data = [NSData dataWithContentsOfFile:notePath options:0
error:&error];
- if (nil == data)
- fprintf(stderr, "skimnotes agent pid %d: error getting RTF notes
(%s)\n", getpid(), [[error description] UTF8String]);
- } else {
- data = [[SKNExtendedAttributeManager sharedManager]
extendedAttributeNamed:SKIM_RTF_NOTES_KEY atPath:[aFile
stringByStandardizingPath] traverseLink:YES error:&error];
- if (nil == data && [error code] != ENOATTR)
- fprintf(stderr, "skimnotes agent pid %d: error getting RTF notes
(%s)\n", getpid(), [[error description] UTF8String]);
- }
+ NSError *error = nil;
+ NSData *data = [[NSFileManager defaultManager] SkimRTFNotesAtPath:aFile
error:&error];
+ if (nil == data)
+ fprintf(stderr, "skimnotes agent pid %d: error getting RTF notes
(%s)\n", getpid(), [[error description] UTF8String]);
return data;
}
- (bycopy NSData *)textNotesAtPath:(in bycopy NSString *)aFile
encoding:(NSStringEncoding)encoding;
{
- NSError *error;
- NSString *string = nil;
- NSString *extension = [[aFile pathExtension] lastPathComponent];
-
- if ([extension caseInsensitiveCompare:@"pdfd"] == NSOrderedSame) {
- NSString *notePath = [self notesFileWithExtension:@"txt" atPath:aFile
error:&error];
- if (notePath)
- string = [NSString stringWithContentsOfFile:notePath
encoding:NSUTF8StringEncoding error:&error];
- if (nil == string)
- fprintf(stderr, "skimnotes agent pid %d: error getting text notes
(%s)\n", getpid(), [[error description] UTF8String]);
- } else {
- string = [[SKNExtendedAttributeManager sharedManager]
propertyListFromExtendedAttributeNamed:SKIM_TEXT_NOTES_KEY atPath:[aFile
stringByStandardizingPath] traverseLink:YES error:&error];
- if (nil == string && [error code] != ENOATTR)
- fprintf(stderr, "skimnotes agent pid %d: error getting text notes
(%s)\n", getpid(), [[error description] UTF8String]);
- }
+ NSError *error = nil;
+ NSString *string = [[NSFileManager defaultManager]
SkimTextNotesAtPath:aFile error:&error];
+ if (nil == string)
+ fprintf(stderr, "skimnotes agent pid %d: error getting text notes
(%s)\n", getpid(), [[error description] UTF8String]);
// Returning the string directly can fail under some conditions. For some
strings with corrupt copy-paste characters (typical for notes), -[NSString
canBeConvertedToEncoding:NSUTF8StringEncoding] returns YES but the actual
conversion fails. A result seems to be that encoding the string also fails,
which causes the DO client to get a timeout. Returning NSUnicodeStringEncoding
data seems to work in those cases (and is safe since we're not going over the
wire between big/little-endian systems).
return [string dataUsingEncoding:encoding];
}
Added: trunk/SkimNotes/SKNUtilities.h
===================================================================
--- trunk/SkimNotes/SKNUtilities.h (rev 0)
+++ trunk/SkimNotes/SKNUtilities.h 2008-07-17 19:02:39 UTC (rev 4241)
@@ -0,0 +1,46 @@
+//
+// SKNUtilities.h
+// SkimNotes
+//
+// Created by Christiaan Hofman on 7/17/08.
+/*
+ This software is Copyright (c) 2008
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+#define SKIM_NOTES_KEY @"net_sourceforge_skim-app_notes"
+#define SKIM_RTF_NOTES_KEY @"net_sourceforge_skim-app_rtf_notes"
+#define SKIM_TEXT_NOTES_KEY @"net_sourceforge_skim-app_text_notes"
+
+extern NSString *SKNTextNotes(NSArray *noteDicts);
+extern NSData *SKNRTFNotes(NSArray *noteDicts);
Added: trunk/SkimNotes/SKNUtilities.m
===================================================================
--- trunk/SkimNotes/SKNUtilities.m (rev 0)
+++ trunk/SkimNotes/SKNUtilities.m 2008-07-17 19:02:39 UTC (rev 4241)
@@ -0,0 +1,100 @@
+//
+// SKNUtilities.m
+// SkimNotes
+//
+// Created by Christiaan Hofman on 7/17/08.
+/*
+ This software is Copyright (c) 2008
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKNUtilities.h"
+
+#define NOTE_PAGE_INDEX_KEY @"pageIndex"
+#define NOTE_TYPE_KEY @"type"
+#define NOTE_CONTENTS_KEY @"contents"
+#define NOTE_TEXT_KEY @"text"
+
+NSString *SKNTextNotes(NSArray *noteDicts) {
+ NSMutableString *textString = [NSMutableString string];
+ NSEnumerator *dictEnum = [noteDicts objectEnumerator];
+ NSDictionary *dict;
+
+ while (dict = [dictEnum nextObject]) {
+ NSString *type = [dict objectForKey:NOTE_TYPE_KEY];
+ NSUInteger pageIndex = [[dict objectForKey:NOTE_PAGE_INDEX_KEY]
unsignedIntValue];
+ NSString *string = [dict objectForKey:NOTE_CONTENTS_KEY];
+ NSAttributedString *text = [dict objectForKey:NOTE_TEXT_KEY];
+
+ if (pageIndex == NSNotFound || pageIndex == UINT_MAX)
+ pageIndex = 0;
+
+ [textString appendFormat:@"* %@, page %lu\n\n", type, (long)pageIndex
+ 1];
+ if ([string length]) {
+ [textString appendString:string];
+ [textString appendString:@" \n\n"];
+ }
+ if ([text length]) {
+ [textString appendString:[text string]];
+ [textString appendString:@" \n\n"];
+ }
+ }
+ return textString;
+}
+
+NSData *SKNRTFNotes(NSArray *noteDicts) {
+ NSMutableAttributedString *attrString = [[[NSMutableAttributedString
alloc] init] autorelease];
+ NSEnumerator *dictEnum = [noteDicts objectEnumerator];
+ NSDictionary *dict;
+
+ while (dict = [dictEnum nextObject]) {
+ NSString *type = [dict objectForKey:NOTE_TYPE_KEY];
+ NSUInteger pageIndex = [[dict objectForKey:NOTE_PAGE_INDEX_KEY]
unsignedIntValue];
+ NSString *string = [dict objectForKey:NOTE_CONTENTS_KEY];
+ NSAttributedString *text = [dict objectForKey:NOTE_TEXT_KEY];
+
+ if (pageIndex == NSNotFound || pageIndex == UINT_MAX)
+ pageIndex = 0;
+
+ [attrString replaceCharactersInRange:NSMakeRange([attrString length],
0) withString:[NSString stringWithFormat:@"* %@, page %lu\n\n", type,
(long)pageIndex + 1]];
+ if ([string length]) {
+ [attrString replaceCharactersInRange:NSMakeRange([attrString
length], 0) withString:string];
+ [attrString replaceCharactersInRange:NSMakeRange([attrString
length], 0) withString:@" \n\n"];
+ }
+ if ([text length]) {
+ [attrString appendAttributedString:text];
+ [attrString replaceCharactersInRange:NSMakeRange([attrString
length], 0) withString:@" \n\n"];
+
+ }
+ }
+ [attrString fixAttributesInRange:NSMakeRange(0, [attrString length])];
+ return [attrString RTFFromRange:NSMakeRange(0, [attrString length])
documentAttributes:nil];
+}
Modified: trunk/SkimNotes/SkimNotes.xcodeproj/project.pbxproj
===================================================================
--- trunk/SkimNotes/SkimNotes.xcodeproj/project.pbxproj 2008-07-17 17:04:15 UTC
(rev 4240)
+++ trunk/SkimNotes/SkimNotes.xcodeproj/project.pbxproj 2008-07-17 19:02:39 UTC
(rev 4241)
@@ -37,6 +37,12 @@
/* Begin PBXBuildFile section */
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ =
{isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */;
};
+ CE37766F0E2FBB7300261604 /* NSFileManager_SKNToolExtensions.m
in Sources */ = {isa = PBXBuildFile; fileRef = CE3776640E2FB47500261604 /*
NSFileManager_SKNToolExtensions.m */; };
+ CE37768C0E2FC26100261604 /* SKNUtilities.h in Headers */ = {isa
= PBXBuildFile; fileRef = CE37768A0E2FC26100261604 /* SKNUtilities.h */; };
+ CE37768D0E2FC26100261604 /* SKNUtilities.m in Sources */ = {isa
= PBXBuildFile; fileRef = CE37768B0E2FC26100261604 /* SKNUtilities.m */; };
+ CE3776950E2FC51900261604 /* SKNUtilities.m in Sources */ = {isa
= PBXBuildFile; fileRef = CE37768B0E2FC26100261604 /* SKNUtilities.m */; };
+ CE3776960E2FC52A00261604 /* SKNUtilities.m in Sources */ = {isa
= PBXBuildFile; fileRef = CE37768B0E2FC26100261604 /* SKNUtilities.m */; };
+ CE3776970E2FC53000261604 /* SKNUtilities.h in Headers */ = {isa
= PBXBuildFile; fileRef = CE37768A0E2FC26100261604 /* SKNUtilities.h */; };
CE3907B00E082C460015B0B7 /* SkimNotes.strings in Resources */ =
{isa = PBXBuildFile; fileRef = CE3907AF0E082C460015B0B7 /* SkimNotes.strings
*/; };
CEA5F54E0E2CEDFB00F65088 /* SkimNotesBase.h in Headers */ =
{isa = PBXBuildFile; fileRef = CEA5F5490E2CED6D00F65088 /* SkimNotesBase.h */;
settings = {ATTRIBUTES = (Public, ); }; };
CEA5F54F0E2CEDFE00F65088 /* NSFileManager_SKNExtensions.h in
Headers */ = {isa = PBXBuildFile; fileRef = CEBA2BD30E05826D0000B2E6 /*
NSFileManager_SKNExtensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -147,6 +153,10 @@
CE17EF880E250E8A00DE06EA /* SkimNotes-Release.xcconfig */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig;
name = "SkimNotes-Release.xcconfig"; path =
"Configurations/SkimNotes-Release.xcconfig"; sourceTree = "<group>"; };
CE17EF890E250E8A00DE06EA /* SkimNotes-Tool.xcconfig */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name =
"SkimNotes-Tool.xcconfig"; path = "Configurations/SkimNotes-Tool.xcconfig";
sourceTree = "<group>"; };
CE17F1BB0E25861700DE06EA /* SkimNotes_Tool_Prefix.pch */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path
= SkimNotes_Tool_Prefix.pch; sourceTree = "<group>"; };
+ CE3776630E2FB47500261604 /* NSFileManager_SKNToolExtensions.h
*/ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.c.h; path = NSFileManager_SKNToolExtensions.h; sourceTree =
"<group>"; };
+ CE3776640E2FB47500261604 /* NSFileManager_SKNToolExtensions.m
*/ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.c.objc; path = NSFileManager_SKNToolExtensions.m; sourceTree =
"<group>"; };
+ CE37768A0E2FC26100261604 /* SKNUtilities.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
SKNUtilities.h; sourceTree = "<group>"; };
+ CE37768B0E2FC26100261604 /* SKNUtilities.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= SKNUtilities.m; sourceTree = "<group>"; };
CE3907AD0E082C2D0015B0B7 /* English */ = {isa =
PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings;
name = English; path = English.lproj/SkimNotes.strings; sourceTree = "<group>";
};
CE3907B40E082C900015B0B7 /* Dutch */ = {isa = PBXFileReference;
lastKnownFileType = text.plist.strings; name = Dutch; path =
Dutch.lproj/SkimNotes.strings; sourceTree = "<group>"; };
CE3907B50E082C930015B0B7 /* French */ = {isa =
PBXFileReference; lastKnownFileType = text.plist.strings; name = French; path =
French.lproj/SkimNotes.strings; sourceTree = "<group>"; };
@@ -334,10 +344,12 @@
CEBA2B610E0566E60000B2E6 /* Tool Classes */ = {
isa = PBXGroup;
children = (
+ CEBA2B5D0E0566DF0000B2E6 /* skimnotes.m */,
+ CE3776630E2FB47500261604 /*
NSFileManager_SKNToolExtensions.h */,
+ CE3776640E2FB47500261604 /*
NSFileManager_SKNToolExtensions.m */,
CEBA2B5A0E0566DF0000B2E6 /* SKNAgentListener.h
*/,
CEBA2B5B0E0566DF0000B2E6 /* SKNAgentListener.m
*/,
CEBA2B5C0E0566DF0000B2E6 /*
SKNAgentListenerProtocol.h */,
- CEBA2B5D0E0566DF0000B2E6 /* skimnotes.m */,
);
name = "Tool Classes";
sourceTree = "<group>";
@@ -347,6 +359,8 @@
children = (
CEBA2B630E05675E0000B2E6 /*
SKNExtendedAttributeManager.h */,
CEBA2B640E05675E0000B2E6 /*
SKNExtendedAttributeManager.m */,
+ CE37768A0E2FC26100261604 /* SKNUtilities.h */,
+ CE37768B0E2FC26100261604 /* SKNUtilities.m */,
);
name = "Shared Classes";
sourceTree = "<group>";
@@ -400,6 +414,7 @@
CEBA2BD50E05826D0000B2E6 /*
NSFileManager_SKNExtensions.h in Headers */,
CEBA2BE20E0587EB0000B2E6 /*
PDFDocument_SKNExtensions.h in Headers */,
CEBA2CD70E058CF00000B2E6 /* SkimNotes.h in
Headers */,
+ CE37768C0E2FC26100261604 /* SKNUtilities.h in
Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -410,6 +425,7 @@
CEA5F54E0E2CEDFB00F65088 /* SkimNotesBase.h in
Headers */,
CEA5F54F0E2CEDFE00F65088 /*
NSFileManager_SKNExtensions.h in Headers */,
CEA5F5510E2CEE0200F65088 /*
SKNExtendedAttributeManager.h in Headers */,
+ CE3776970E2FC53000261604 /* SKNUtilities.h in
Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -598,6 +614,7 @@
CEBA2B8E0E0569010000B2E6 /*
SKNPDFAnnotationNote.m in Sources */,
CEBA2BD60E05826D0000B2E6 /*
NSFileManager_SKNExtensions.m in Sources */,
CEBA2BE30E0587EB0000B2E6 /*
PDFDocument_SKNExtensions.m in Sources */,
+ CE37768D0E2FC26100261604 /* SKNUtilities.m in
Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -607,6 +624,7 @@
files = (
CEA5F5500E2CEDFF00F65088 /*
NSFileManager_SKNExtensions.m in Sources */,
CEA5F5520E2CEE0300F65088 /*
SKNExtendedAttributeManager.m in Sources */,
+ CE3776960E2FC52A00261604 /* SKNUtilities.m in
Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -617,6 +635,8 @@
CEBA2B5E0E0566DF0000B2E6 /* SKNAgentListener.m
in Sources */,
CEBA2B5F0E0566DF0000B2E6 /* skimnotes.m in
Sources */,
CEBA2B650E05675E0000B2E6 /*
SKNExtendedAttributeManager.m in Sources */,
+ CE37766F0E2FBB7300261604 /*
NSFileManager_SKNToolExtensions.m in Sources */,
+ CE3776950E2FC51900261604 /* SKNUtilities.m in
Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: trunk/SkimNotes/skimnotes.m
===================================================================
--- trunk/SkimNotes/skimnotes.m 2008-07-17 17:04:15 UTC (rev 4240)
+++ trunk/SkimNotes/skimnotes.m 2008-07-17 19:02:39 UTC (rev 4241)
@@ -1,17 +1,14 @@
#import <Foundation/Foundation.h>
-#import "SKNExtendedAttributeManager.h"
+#import "NSFileManager_SKNToolExtensions.h"
#import "SKNAgentListener.h"
-#define SKIM_NOTES_KEY @"net_sourceforge_skim-app_notes"
-#define SKIM_RTF_NOTES_KEY @"net_sourceforge_skim-app_rtf_notes"
-#define SKIM_TEXT_NOTES_KEY @"net_sourceforge_skim-app_text_notes"
-
-static char *usageStr = "Usage:\n skimnotes get [-format skim|text|rtf]
PDF_FILE [SKIM_FILE|RTF_FILE|TEXT_FILE|-]\n skimnotes set PDF_FILE
[SKIM_FILE|-]\n skimnotes remove PDF_FILE\n skimnotes agent [SERVER_NAME]\n
skimnotes protocol\n skimnotes help [VERB]\n skimnotes version";
+static char *usageStr = "Usage:\n skimnotes get [-format skim|text|rtf]
PDF_FILE [SKIM_FILE|RTF_FILE|TEXT_FILE|-]\n skimnotes set PDF_FILE
[SKIM_FILE|-]\n skimnotes remove PDF_FILE\n skimnotes convert
PDF_FILE|PDF_BUNDLE [PDF_BUNDLE|PDF_FILE]\n skimnotes agent [SERVER_NAME]\n
skimnotes protocol\n skimnotes help [VERB]\n skimnotes version";
static char *versionStr = "SkimNotes command-line client, version 2.2.2";
+static char *getHelpStr = "skimnotes get: read Skim notes from a PDF\nUsage:
skimnotes get [-format skim|text|rtf] PDF_FILE [NOTES_FILE|-]\n\nReads Skim,
Text, or RTF notes from extended attributes of PDF_FILE and writes to
NOTES_FILE or standard output.\nUses notes file with same base name as PDF_FILE
if SKIM_FILE is not provided.\nReads Skim notes when no format is provided.";
static char *setHelpStr = "skimnotes set: write Skim notes to a PDF\nUsage:
skimnotes set PDF_FILE [SKIM_FILE|-]\n\nWrites notes to extended attributes of
PDF_FILE from SKIM_FILE or standard input.\nUses notes file with same base name
as PDF_FILE if SKIM_FILE is not provided.";
-static char *getHelpStr = "skimnotes get: read Skim notes from a PDF\nUsage:
skimnotes get [-format skim|text|rtf] PDF_FILE [NOTES_FILE|-]\n\nReads Skim,
Text, or RTF notes from extended attributes of PDF_FILE and writes to
NOTES_FILE or standard output.\nUses notes file with same base name as PDF_FILE
if SKIM_FILE is not provided.\nReads Skim notes when no format is provided.";
static char *removeHelpStr = "skimnotes remove: delete Skim notes from a
PDF\nUsage: skimnotes remove PDF_FILE\n\nRemoves the Skim notes from the
extended attributes of PDF_FILE.";
+static char *convertHelpStr = "skimnotes convert: convert between a PDF file
and a PDF bundle\nUsage: skimnotes convert PDF_FILE|PDF_BUNDLE
[PDF_BUNDLE|PDF_FILE]\n\nConverts a PDF file to a PDF bundle or a PDF bundle to
a PDF file.\nUses a file with same base name as the first file argument if the
second file argument is not provided.";
static char *agentHelpStr = "skimnotes agent: run the Skim Notes agent\nUsage:
skimnotes agent [SERVER_NAME]\n\nRuns a Skim Notes agent server with server
name SERVER_NAME, to which a Cocoa application can connect using DO.\nWhen
SERVER_NAME is not provided, a unique name is generated and returned on
standard output.\nThe DO server conforms to the following formal [EMAIL
PROTECTED] SKNAgentListenerProtocol\n- (bycopy NSData *)SkimNotesAtPath:(in
bycopy NSString *)aFile;\n- (bycopy NSData *)RTFNotesAtPath:(in bycopy NSString
*)aFile;\n- (bycopy NSData *)textNotesAtPath:(in bycopy NSString *)aFile
encoding:(NSStringEncoding)encoding;[EMAIL PROTECTED]";
static char *protocolHelpStr = "skimnotes protocol: write the DO server
protocol to standard output\nUsage: skimnotes protocol\n\nWrite the DO server
protocol for the agent to standard output.";
static char *helpHelpStr = "skimnotes help: get help on the skimnotes
tool\nUsage: skimnotes help [VERB]\n\nGet help on the verb VERB.";
@@ -22,6 +19,7 @@
#define ACTION_GET_STRING @"get"
#define ACTION_SET_STRING @"set"
#define ACTION_REMOVE_STRING @"remove"
+#define ACTION_CONVERT_STRING @"convert"
#define ACTION_AGENT_STRING @"agent"
#define ACTION_PROTOCOL_STRING @"protocol"
#define ACTION_VERSION_STRING @"version"
@@ -35,6 +33,7 @@
#define FORMAT_RTF_STRING @"rtf"
#define PDF_EXTENSION @"pdf"
+#define PDFD_EXTENSION @"pdfd"
#define SKIM_EXTENSION @"skim"
#define TXT_EXTENSION @"txt"
#define TEXT_EXTENSION @"text"
@@ -51,6 +50,7 @@
SKNActionGet,
SKNActionSet,
SKNActionRemove,
+ SKNActionConvert,
SKNActionAgent,
SKNActionProtocol,
SKNActionVersion,
@@ -71,6 +71,8 @@
return SKNActionSet;
else if ([actionString caseInsensitiveCompare:ACTION_REMOVE_STRING] ==
NSOrderedSame)
return SKNActionRemove;
+ else if ([actionString caseInsensitiveCompare:ACTION_CONVERT_STRING] ==
NSOrderedSame)
+ return SKNActionConvert;
else if ([actionString caseInsensitiveCompare:ACTION_AGENT_STRING] ==
NSOrderedSame)
return SKNActionAgent;
else if ([actionString caseInsensitiveCompare:ACTION_PROTOCOL_STRING] ==
NSOrderedSame)
@@ -149,6 +151,9 @@
case SKNActionRemove:
WRITE_OUT(removeHelpStr);
break;
+ case SKNActionConvert:
+ WRITE_OUT(convertHelpStr);
+ break;
case SKNActionAgent:
WRITE_OUT(agentHelpStr);
break;
@@ -199,17 +204,24 @@
NSFileManager *fm = [NSFileManager defaultManager];
NSString *pdfPath = SKNNormalizedPath([args objectAtIndex:offset]);
NSString *notesPath = argc < offset + 2 ? nil :
SKNNormalizedPath([args objectAtIndex:offset + 1]);
+ BOOL isBundle = NO;
BOOL isDir = NO;
NSError *error = nil;
+ if ([[pdfPath pathExtension] caseInsensitiveCompare:PDFD_EXTENSION] ==
NSOrderedSame)
+ isBundle = YES;
+ else if ([[pdfPath pathExtension]
caseInsensitiveCompare:PDF_EXTENSION] != NSOrderedSame)
+ pdfPath = [[pdfPath stringByDeletingPathExtension]
stringByAppendingPathExtension:PDF_EXTENSION];
+
if (action != SKNActionRemove && notesPath == nil) {
- notesPath = [[pdfPath stringByDeletingPathExtension]
stringByAppendingPathExtension:format == SKNFormatText ? TXT_EXTENSION : format
== SKNFormatRTF ? RTF_EXTENSION : SKIM_EXTENSION];
+ notesPath = [pdfPath stringByDeletingPathExtension];
+ if (action == SKNActionConvert)
+ notesPath = [notesPath stringByAppendingPathExtension:isBundle
? PDF_EXTENSION : PDFD_EXTENSION];
+ else
+ notesPath = [notesPath stringByAppendingPathExtension:format
== SKNFormatText ? TXT_EXTENSION : format == SKNFormatRTF ? RTF_EXTENSION :
SKIM_EXTENSION];
}
- if ([[pdfPath pathExtension] caseInsensitiveCompare:PDF_EXTENSION] !=
NSOrderedSame)
- pdfPath = [[pdfPath stringByDeletingPathExtension]
stringByAppendingPathExtension:PDF_EXTENSION];
-
- if ([fm fileExistsAtPath:pdfPath isDirectory:&isDir] == NO || isDir) {
+ if ([fm fileExistsAtPath:pdfPath isDirectory:&isDir] == NO || isBundle
!= isDir) {
error = [NSError errorWithDomain:NSPOSIXErrorDomain code:ENOENT
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"PDF file does not exist",
NSLocalizedDescriptionKey, nil]];
} else if (action == SKNActionGet) {
NSData *data = nil;
@@ -222,21 +234,12 @@
else
format = SKNFormatSkim;
}
- SKNExtendedAttributeManager *eam = [SKNExtendedAttributeManager
sharedManager];
- if (format == SKNFormatSkim) {
- data = [eam extendedAttributeNamed:SKIM_NOTES_KEY
atPath:pdfPath traverseLink:YES error:&error];
- if (data == nil && [error code] == ENOATTR)
- data = [NSData data];
- } else if (format == SKNFormatText) {
- NSString *string = [eam
propertyListFromExtendedAttributeNamed:SKIM_TEXT_NOTES_KEY atPath:pdfPath
traverseLink:YES error:&error];
- data = [string dataUsingEncoding:NSUTF8StringEncoding];
- if (string == nil && [error code] == ENOATTR)
- data = [NSData data];
- } else if (format == SKNFormatRTF) {
- data = [eam extendedAttributeNamed:SKIM_RTF_NOTES_KEY
atPath:pdfPath traverseLink:YES error:&error];
- if (data == nil && [error code] == ENOATTR)
- data = [NSData data];
- }
+ if (format == SKNFormatSkim)
+ data = [fm SkimNotesAtPath:pdfPath error:&error];
+ else if (format == SKNFormatText)
+ data = [[fm SkimTextNotesAtPath:pdfPath error:&error]
dataUsingEncoding:NSUTF8StringEncoding];
+ else if (format == SKNFormatRTF)
+ data = [fm SkimRTFNotesAtPath:pdfPath error:&error];
if (data) {
if ([notesPath isEqualToString:STD_IN_OUT_FILE]) {
if ([data length])
@@ -260,26 +263,34 @@
data = [[NSFileHandle fileHandleWithStandardInput]
readDataToEndOfFile];
else
data = [NSData dataWithContentsOfFile:notesPath];
- if (data) {
- SKNExtendedAttributeManager *eam =
[SKNExtendedAttributeManager sharedManager];
- success = [eam removeExtendedAttribute:SKIM_NOTES_KEY
atPath:pdfPath traverseLink:YES error:&error] || [error code] == ENOATTR;
- [eam removeExtendedAttribute:SKIM_RTF_NOTES_KEY atPath:pdfPath
traverseLink:YES error:NULL];
- [eam removeExtendedAttribute:SKIM_TEXT_NOTES_KEY
atPath:pdfPath traverseLink:YES error:NULL];
- if (success && [data length])
- success = [eam setExtendedAttributeNamed:SKIM_NOTES_KEY
toValue:data atPath:pdfPath options:0 error:&error];
+ if ([data length])
+ success = [fm writeSkimNotes:data textNotes:nil RTFNotes:nil
atPath:pdfPath error:&error];
+ else if (data)
+ success = [fm removeSkimNotesAtPath:pdfPath error:&error];
+ } else if (action == SKNActionRemove) {
+ success = [fm removeSkimNotesAtPath:pdfPath error:&error];
+ } else if (action == SKNActionConvert) {
+ if (isBundle) {
+ success = [fm createDirectoryAtPath:notesPath attributes:nil];
+ } else {
+ NSString *pdfFilePath = nil;
+ NSArray *files = [fm subpathsAtPath:pdfPath];
+ NSString *filename = [[[pdfPath 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];
+ }
+ if (filename)
+ pdfFilePath = [pdfPath
stringByAppendingPathComponent:filename];
+ success = [fm copyPath:pdfFilePath toPath:notesPath
handler:nil];
}
- } else if (action == SKNActionRemove) {
- SKNExtendedAttributeManager *eam = [SKNExtendedAttributeManager
sharedManager];
- BOOL success1 = [eam removeExtendedAttribute:SKIM_NOTES_KEY
atPath:pdfPath traverseLink:YES error:&error];
- if (success1 == NO && [error code] == ENOATTR)
- success1 = YES;
- BOOL success2 = [eam removeExtendedAttribute:SKIM_RTF_NOTES_KEY
atPath:pdfPath traverseLink:YES error:&error];
- if (success2 == NO && [error code] == ENOATTR)
- success2 = YES;
- BOOL success3 = [eam removeExtendedAttribute:SKIM_TEXT_NOTES_KEY
atPath:pdfPath traverseLink:YES error:&error];
- if (success3 == NO && [error code] == ENOATTR)
- success3 = YES;
- success = success1 && success2 && success3;
+ if (success) {
+ NSData *notesData = [fm SkimNotesAtPath:pdfPath error:&error];
+ NSString *textNotes = [fm SkimTextNotesAtPath:pdfPath
error:&error];
+ NSData *rtfNotesData = [fm SkimRTFNotesAtPath:pdfPath
error:&error];
+ if (notesData)
+ success = [fm writeSkimNotes:notesData textNotes:textNotes
RTFNotes:rtfNotesData atPath:notesPath error:&error];
+ }
}
if (success == NO && error)
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit