Revision: 22455
http://sourceforge.net/p/bibdesk/svn/22455
Author: hofman
Date: 2018-07-23 12:09:33 +0000 (Mon, 23 Jul 2018)
Log Message:
-----------
Allow escaped character specifiers in optional arguments in format
Modified Paths:
--------------
trunk/bibdesk/BDSKFormatParser.m
Modified: trunk/bibdesk/BDSKFormatParser.m
===================================================================
--- trunk/bibdesk/BDSKFormatParser.m 2018-07-23 06:30:23 UTC (rev 22454)
+++ trunk/bibdesk/BDSKFormatParser.m 2018-07-23 12:09:33 UTC (rev 22455)
@@ -64,8 +64,10 @@
static NSCharacterSet *validOptArg3SpecifierChars = nil;
static NSCharacterSet *validOptArg2SpecifierChars = nil;
static NSCharacterSet *validAuthorSpecifierChars = nil;
+static NSCharacterSet *optArgStopChars = nil;
static NSDictionary *specAttr = nil;
static NSDictionary *paramAttr = nil;
+static NSDictionary *paramTextAttr = nil;
static NSDictionary *argAttr = nil;
static NSDictionary *textAttr = nil;
static NSDictionary *errorAttr = nil;
@@ -79,6 +81,26 @@
return NO;
}
+static BOOL scanOptArg(NSScanner *scanner, NSString **result) {
+ NSMutableString *tmpString = nil;
+ NSString *string = nil;
+ unichar escapeChar;
+ while (YES) {
+ if ([scanner scanUpToCharactersFromSet:optArgStopChars
intoString:&string] && tmpString != nil)
+ [tmpString appendString:string];
+ if ([scanner scanString:@"%" intoString:NULL] == NO || [scanner
scanCharacter:&escapeChar] == NO)
+ break;
+ if (tmpString == nil)
+ tmpString = [NSMutableString stringWithString:string ?: @""];
+ [tmpString appendFormat:@"%C", escapeChar];
+ }
+ if ([tmpString length] == 0 && [string length] == 0)
+ return NO;
+ if (result)
+ *result = tmpString ?: string;
+ return YES;
+}
+
+ (void)initialize {
BDSKINITIALIZE;
@@ -92,11 +114,13 @@
validOptArg3SpecifierChars = [[NSCharacterSet
characterSetWithCharactersInString:@"APws"] retain];
validOptArg2SpecifierChars = [[NSCharacterSet
characterSetWithCharactersInString:@"apk"] retain];
validAuthorSpecifierChars = [[NSCharacterSet
characterSetWithCharactersInString:@"aApP"] retain];
-
+ optArgStopChars = [[NSCharacterSet
characterSetWithCharactersInString:@"%]"] retain];
+
NSFont *font = [NSFont systemFontOfSize:0];
NSFont *boldFont = [NSFont boldSystemFontOfSize:0];
specAttr = [[NSDictionary alloc] initWithObjectsAndKeys:boldFont,
NSFontAttributeName, [NSColor blueColor], NSForegroundColorAttributeName, nil];
paramAttr = [[NSDictionary alloc] initWithObjectsAndKeys:boldFont,
NSFontAttributeName, [NSColor colorWithCalibratedRed:0.0 green:0.5 blue:0.0
alpha:1.0], NSForegroundColorAttributeName, nil];
+ paramTextAttr = [[NSDictionary alloc] initWithObjectsAndKeys:boldFont,
NSFontAttributeName, [NSColor colorWithCalibratedRed:0.0 green:0.7 blue:0.0
alpha:1.0], NSForegroundColorAttributeName, nil];
argAttr = [[NSDictionary alloc] initWithObjectsAndKeys:font,
NSFontAttributeName, [NSColor controlTextColor],
NSForegroundColorAttributeName, nil];
textAttr = [[NSDictionary alloc] initWithObjectsAndKeys:boldFont,
NSFontAttributeName, [NSColor controlTextColor],
NSForegroundColorAttributeName, nil];
errorAttr = [[NSDictionary alloc] initWithObjectsAndKeys:font,
NSFontAttributeName, [NSColor redColor], NSForegroundColorAttributeName, nil];
@@ -150,11 +174,11 @@
if (NO == [scanner isAtEnd]) {
// look for [separator]
if ([scanner scanString:@"["
intoString:NULL]) {
- if (NO == [scanner
scanUpToString:@"]" intoString:&authSep]) authSep = @"";
+ if (NO ==
scanOptArg(scanner, &authSep)) authSep = @"";
[scanner
scanString:@"]" intoString:NULL];
// look for [etal]
if ([scanner
scanString:@"[" intoString:NULL]) {
- if (NO ==
[scanner scanUpToString:@"]" intoString:&etal]) etal = @"";
+ if (NO ==
scanOptArg(scanner, &etal)) etal = @"";
[scanner
scanString:@"]" intoString:NULL];
}
}
@@ -222,15 +246,15 @@
if (NO == [scanner isAtEnd]) {
// look for [author separator]
if ([scanner scanString:@"["
intoString:NULL]) {
- if (NO == [scanner
scanUpToString:@"]" intoString:&authSep]) authSep = @"";
+ if (NO ==
scanOptArg(scanner, &authSep)) authSep = @"";
[scanner
scanString:@"]" intoString:NULL];
// look for [name
separator]
if ([scanner
scanString:@"[" intoString:NULL]) {
- if (NO ==
[scanner scanUpToString:@"]" intoString:&nameSep]) nameSep = @"";
+ if (NO ==
scanOptArg(scanner, &nameSep)) nameSep = @"";
[scanner
scanString:@"]" intoString:NULL];
// look for
[etal]
if ([scanner
scanString:@"[" intoString:NULL]) {
- if (NO
== [scanner scanUpToString:@"]" intoString:&etal]) etal = @"";
+ if (NO
== scanOptArg(scanner, &etal)) etal = @"";
[scanner scanString:@"]" intoString:NULL];
}
}
@@ -317,7 +341,7 @@
NSString *numString = nil;
NSString *title = [pub title];
if ([scanner scanString:@"[" intoString:NULL]) {
- if ([scanner scanUpToString:@"]"
intoString:&numString])
+ if (scanOptArg(scanner, &numString))
smallWordLength = (NSUInteger)[numString
integerValue];
else
smallWordLength = 0;
@@ -410,10 +434,10 @@
NSString *slash = (isLocalFile) ? @"-"
: @"/";
NSString *sep = nil;
if ([scanner scanString:@"["
intoString:NULL]) {
- if (NO == [scanner
scanUpToString:@"]" intoString:&slash]) slash = @"";
+ if (NO == scanOptArg(scanner,
&slash)) slash = @"";
[scanner scanString:@"]"
intoString:NULL];
if ([scanner scanString:@"[" intoString:NULL]) {
- if (NO == [scanner scanUpToString:@"]"
intoString:&sep]) sep = @"";
+ if (NO == scanOptArg(scanner, &sep)) sep = @"";
[scanner scanString:@"]" intoString:NULL];
}
}
@@ -508,7 +532,7 @@
// old file extension without period
NSString *defaultExt = @"";
if ([scanner scanString:@"["
intoString:NULL]) {
- if (NO == [scanner
scanUpToString:@"]" intoString:&defaultExt]) defaultExt = @"";
+ if (NO == scanOptArg(scanner,
&defaultExt)) defaultExt = @"";
[scanner scanString:@"]"
intoString:NULL];
}
NSString *filename = nil;
@@ -549,7 +573,7 @@
[scanner scanString:@"}"
intoString:NULL]) {
// look for [slash]
if ([scanner scanString:@"["
intoString:NULL]) {
- if (NO == [scanner
scanUpToString:@"]" intoString:&slash]) slash = @"";
+ if (NO ==
scanOptArg(scanner, &slash)) slash = @"";
[scanner
scanString:@"]" intoString:NULL];
}
@@ -590,14 +614,14 @@
[scanner scanString:@"}"
intoString:NULL]) {
// look for [sep]
if ([scanner scanString:@"[" intoString:NULL]) {
- if (NO == [scanner scanUpToString:@"]"
intoString:&sepChars]) sepChars = @" ";
+ if (NO == scanOptArg(scanner, &sepChars)) sepChars
= @" ";
[scanner scanString:@"]" intoString:NULL];
// look for [slash]
if ([scanner scanString:@"[" intoString:NULL]) {
- if (NO == [scanner scanUpToString:@"]"
intoString:&slash]) slash = @"";
+ if (NO == scanOptArg(scanner, &slash)) slash =
@"";
[scanner scanString:@"]" intoString:NULL];
if ([scanner scanString:@"[" intoString:NULL])
{
- if (NO == [scanner scanUpToString:@"]"
intoString:&sep]) sep = @"";
+ if (NO == scanOptArg(scanner, &sep)) sep =
@"";
[scanner scanString:@"]" intoString:NULL];
}
}
@@ -674,15 +698,15 @@
[scanner scanString:@"}"
intoString:NULL]) {
// look for [yes value]
if ([scanner scanString:@"["
intoString:NULL]) {
- if (NO == [scanner
scanUpToString:@"]" intoString:&yesValue]) yesValue = @"";
+ if (NO ==
scanOptArg(scanner, &yesValue)) yesValue = @"";
[scanner
scanString:@"]" intoString:NULL];
// look for [no value]
if ([scanner scanString:@"[" intoString:NULL]) {
- if (NO == [scanner scanUpToString:@"]"
intoString:&noValue]) noValue = @"";
+ if (NO == scanOptArg(scanner, &noValue))
noValue = @"";
[scanner scanString:@"]" intoString:NULL];
// look for [mixed value]
if ([scanner scanString:@"[" intoString:NULL])
{
- if (NO == [scanner scanUpToString:@"]"
intoString:&mixedValue]) mixedValue = @"";
+ if (NO == scanOptArg(scanner,
&mixedValue)) mixedValue = @"";
[scanner scanString:@"]" intoString:NULL];
}
}
@@ -786,7 +810,7 @@
prefixStr = parsedStr;
parsedStr = [NSMutableString
string];
if ([scanner scanString:@"[" intoString:NULL]) {
- [scanner scanUpToString:@"]"
intoString:&uniqueSeparator];
+ scanOptArg(scanner, &uniqueSeparator);
[scanner scanString:@"]" intoString:NULL];
}
if (NO == [scanner
scanUnsignedInteger:&uniqueNumber]) uniqueNumber = 1;
@@ -1111,16 +1135,38 @@
if (NO == [scanner isAtEnd]) {
NSInteger i, numOpts =
([validOptArg3SpecifierChars characterIsMember:specifier] ? 3 :
[validOptArg2SpecifierChars characterIsMember:specifier] ? 2 : 1);
for (i = 0; i < numOpts && [scanner
scanString:@"[" intoString: NULL]; i++) {
- if (NO == [scanner scanUpToString:@"]"
intoString:&string])
- string = @"";
+ NSMutableString *optArgString = [NSMutableString string];
+ while (YES) {
+ if ([scanner scanUpToCharactersFromSet:optArgStopChars
intoString:&string]) {
+ if (specifier != 'w' || i > 0)
+ string = [self stringBySanitizingString:string
forField:fieldName];
+ [optArgString appendString:string];
+ }
+ if ([scanner scanString:@"%" intoString:NULL] == NO)
+ break;
+ unichar escapeChar;
+ if ([scanner scanCharacter:&escapeChar] == NO) {
+ errorMsg = NSLocalizedString(@"Empty specifier %
at end of format.", @"Error description");
+ break;
+ }
+ else if ([validEscapeSpecifierChars
characterIsMember:escapeChar] == NO) {
+ errorMsg = [NSString
stringWithFormat:NSLocalizedString(@"Invalid specifier %%%C in format.",
@"Error description"), escapeChar];
+ break;
+ }
+ else if ([invalidCharSet
characterIsMember:escapeChar]) {
+ errorMsg = [NSString stringWithFormat:
NSLocalizedString(@"Invalid escape specifier %%%C in format.", @"Error
description"), escapeChar];
+ break;
+ }
+ [optArgString appendFormat:@"%%%C", escapeChar];
+ }
+ if (errorMsg != nil)
+ break;
if (NO == [scanner scanString:@"]"
intoString:NULL]) {
errorMsg = [NSString
stringWithFormat: NSLocalizedString(@"Missing \"]\" after specifier %%%C.",
@"Error description"), specifier];
break;
}
- if (specifier != 'w' || i > 0)
- string = [self stringBySanitizingString:string
forField:fieldName];
AppendStringToFormatStrings(@"[",
paramAttr);
- AppendStringToFormatStrings(string,
paramAttr);
+
AppendStringToFormatStrings(optArgString, paramTextAttr);
AppendStringToFormatStrings(@"]",
paramAttr);
}
if (errorMsg != nil)
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit