Pickcharparser now can handle non-default checkbox formats

This commit is contained in:
Michael Starke 2017-12-12 15:19:24 +01:00
parent 2d5974982e
commit 24c8d8efc8
4 changed files with 112 additions and 34 deletions

View File

@ -14,8 +14,6 @@
@property (readonly) BOOL convertToDownArrows;
@property (readonly) NSUInteger pickCount; // count to pick - 0 if unlimted
@property (readonly) NSUInteger checkboxOffset;
@property (readonly, copy) NSString *checkboxFormat;
/**
Initializes the parser with the given option string.

View File

@ -15,7 +15,8 @@
typedef NS_ENUM(NSInteger, MPPickCharOffsetType) {
MPPickCharOffsetTypeNone,
MPPickCharOffsetTypeCharacter,
MPPickCharOffsetTypeLowerCaseCharacter,
MPPickCharOffsetTypeUpperCaseCharacter,
MPPickCharOffsetTypeNumber,
};
@ -25,12 +26,18 @@ struct MPPickCharOffset {
};
typedef struct MPPickCharOffset MPPickCharOffset;
MPPickCharOffset MPMakePickCharCharacterOffset(NSUInteger offset) {
MPPickCharOffset offsetStruct = {MPPickCharOffsetTypeCharacter, offset};
MPPickCharOffset MPMakePickCharUpperCaseCharacterOffset(unichar c) {
MPPickCharOffset offsetStruct = {MPPickCharOffsetTypeUpperCaseCharacter, c - 'A'};
return offsetStruct;
}
MPPickCharOffset MPMakePickCharNumberOffset(NSUInteger offset) {
MPPickCharOffset offsetStruct = {MPPickCharOffsetTypeNumber, offset};
MPPickCharOffset MPMakePickCharLowerCaseCharacterOffset(unichar c) {
MPPickCharOffset offsetStruct = {MPPickCharOffsetTypeLowerCaseCharacter, c - 'a'};
return offsetStruct;
}
MPPickCharOffset MPMakePickCharNumberOffset(unichar c) {
MPPickCharOffset offsetStruct = {MPPickCharOffsetTypeNumber, c - '0'};
return offsetStruct;
}
@ -39,6 +46,19 @@ MPPickCharOffset MPMakeInvalidPickCharOffset(void) {
return offset;
}
MPPickCharOffset MPMakePickCharOffset(unichar character) {
if(character >= '0' && character <= '9') {
return MPMakePickCharNumberOffset(character);
}
else if(character >= 'a' && character <= 'z') {
return MPMakePickCharLowerCaseCharacterOffset(character);
}
else if(character >= 'A' && character <= 'Z') {
return MPMakePickCharUpperCaseCharacterOffset(character);
}
return MPMakeInvalidPickCharOffset();
}
BOOL MPIsValidPickCharOffset(MPPickCharOffset offset) {
return (offset.type != MPPickCharOffsetTypeNone);
}
@ -48,9 +68,22 @@ NSInteger numberOffset(MPPickCharOffset offset) {
}
NSInteger characterOffset(MPPickCharOffset offset) {
return (offset.type == MPPickCharOffsetTypeCharacter ? offset.offset : 0);
switch(offset.type) {
case MPPickCharOffsetTypeUpperCaseCharacter:
case MPPickCharOffsetTypeLowerCaseCharacter:
return offset.offset;
default:
return 0;
}
}
typedef NSUInteger (^MPPickcharOffsetConverter)(NSInteger offset);
@interface MPPickcharsParser () {
NSDictionary <NSValue *, MPPickcharOffsetConverter> *_offsetConverter;
}
@end
@implementation MPPickcharsParser
- (instancetype)init {
@ -65,6 +98,7 @@ NSInteger characterOffset(MPPickCharOffset offset) {
_checkboxOffset = 0;
_convertToDownArrows = NO;
_hideCharacters = YES;
_offsetConverter = nil;
[self _parseOptions:options];
}
return self;
@ -75,23 +109,13 @@ NSInteger characterOffset(MPPickCharOffset offset) {
return string;
}
NSMutableString *mutableString = [[NSMutableString alloc] init];
BOOL isFirst = NO;
for(NSString *substring in string.composedCharacters) {
if(substring.length != 1) {
NSLog(@"Pickchars: Unsupported character %@ for conversion to down arrows, skipping!", substring);
continue;
}
MPPickCharOffset offset = MPMakeInvalidPickCharOffset();
unichar character = [substring characterAtIndex:0];
if(character >= '0' && character <= '9') {
offset = MPMakePickCharNumberOffset(character - '0');
}
else if(character >= 'a' && character <= 'z') {
offset = MPMakePickCharCharacterOffset(character - 'a');
}
else if(character >= 'A' && character <= 'Z') {
offset = MPMakePickCharCharacterOffset(character - 'A');
}
MPPickCharOffset offset = MPMakePickCharOffset(character);
[self _appendKeyCommandsForOffset:offset toString:mutableString];
}
return [mutableString copy];
@ -102,18 +126,13 @@ NSInteger characterOffset(MPPickCharOffset offset) {
return;
}
NSUInteger actualOffset = self.checkboxOffset;
switch(offset.type) {
case MPPickCharOffsetTypeNumber:
actualOffset += offset.offset;
break;
case MPPickCharOffsetTypeCharacter:
actualOffset += offset.offset;
break;
case MPPickCharOffsetTypeNone:
default:
break;
MPPickcharOffsetConverter convertBlock = _offsetConverter[@(offset.type)];
if(convertBlock) {
actualOffset += convertBlock(offset.offset);
}
else {
actualOffset += offset.offset;
}
/* todo respect format definition */
while (actualOffset--) {
[string appendString:kKPKAutotypeDown];
}
@ -201,7 +220,68 @@ NSInteger characterOffset(MPPickCharOffset offset) {
return NO;
}
if(NSOrderedSame == [key compare:kKPKPlaceholderPickCharsOptionConvertFormat options:NSCaseInsensitiveSearch]) {
self.checkboxFormat = option;
if(option.length == 0) {
/* interpret no optoins as default too*/
return YES;
}
/* parse range format */
NSMutableDictionary *tmpOffsetMap = [[NSMutableDictionary alloc] init];
NSUInteger index = 0;
NSUInteger collectedOffset = 0;
while(index < option.length) {
NSString *formatOption = [option substringWithRange:NSMakeRange(index, 1)];
if([formatOption isEqualToString:@"0"]) {
if(tmpOffsetMap[@(MPPickCharOffsetTypeNumber)]) {
return NO; // double definition!
}
tmpOffsetMap[@(MPPickCharOffsetTypeNumber)] = ^NSInteger(NSUInteger offset) {
return offset + collectedOffset;
};
collectedOffset += 10;
}
else if([formatOption isEqualToString:@"1"]) {
if(tmpOffsetMap[@(MPPickCharOffsetTypeNumber)]) {
return NO; // double definition!
}
tmpOffsetMap[@(MPPickCharOffsetTypeNumber)] = ^NSInteger(NSUInteger offset) {
NSInteger tmpOffset = offset - 1;
if(tmpOffset < 0) {
tmpOffset += 10;
}
return tmpOffset + collectedOffset;
};
collectedOffset += 10;
}
else if([formatOption isEqualToString:@"a"]) {
if(tmpOffsetMap[@(MPPickCharOffsetTypeLowerCaseCharacter)]) {
return NO; // double definition!
}
tmpOffsetMap[@(MPPickCharOffsetTypeLowerCaseCharacter)] = ^NSInteger(NSUInteger offset) {
return offset + collectedOffset;
};
collectedOffset += 26;
}
else if([formatOption isEqualToString:@"A"]) {
if(tmpOffsetMap[@(MPPickCharOffsetTypeUpperCaseCharacter)]) {
return NO; // double definition!
}
tmpOffsetMap[@(MPPickCharOffsetTypeUpperCaseCharacter)] = ^NSInteger(NSUInteger offset) {
return offset + collectedOffset;
};
collectedOffset += 26;
}
else if([formatOption isEqualToString:@"?"]) {
/* just collect skips */
collectedOffset++;
}
else {
return NO;
}
index++;
}
_offsetConverter = [tmpOffsetMap copy];
return YES;
}
return NO;

View File

@ -14,6 +14,5 @@
@property NSUInteger checkboxOffset;
@property BOOL convertToDownArrows;
@property BOOL hideCharacters;
@property (copy) NSString *checkboxFormat;
@end

View File

@ -23,7 +23,9 @@
XCTAssertEqual(NO, parser.hideCharacters);
XCTAssertEqual(YES, parser.convertToDownArrows);
XCTAssertEqual(11, parser.checkboxOffset);
XCTAssertEqualObjects(@"0?aA", parser.checkboxFormat);
NSString *result = [parser processPickedString:@"1B0f"];
}
@ -33,7 +35,6 @@
XCTAssertEqual(YES, parser.hideCharacters); // option invalid, default is YES
XCTAssertEqual(NO, parser.convertToDownArrows); // option was invalid, default is NO
XCTAssertEqual(20, parser.checkboxOffset);
XCTAssertEqualObjects(@"0A", parser.checkboxFormat);
}
- (void)testConvertToDownArrows {