From 2163f24509e512c2b5b2dd253075d067cca6db94 Mon Sep 17 00:00:00 2001 From: Kim Wittenburg Date: Wed, 23 Apr 2014 03:11:07 +0200 Subject: [PATCH] Renamed MPRange to MPRangePath Added MPRangeExtension Category on MPExpression --- MathPad/MPRangePath.h | 47 +++++++++++++ MathPad/MPRangePath.m | 153 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 MathPad/MPRangePath.h create mode 100644 MathPad/MPRangePath.m diff --git a/MathPad/MPRangePath.h b/MathPad/MPRangePath.h new file mode 100644 index 0000000..cdc101d --- /dev/null +++ b/MathPad/MPRangePath.h @@ -0,0 +1,47 @@ +// +// MPRange.h +// MathPad +// +// Created by Kim Wittenburg on 18.04.14. +// Copyright (c) 2014 Kim Wittenburg. All rights reserved. +// + +#import "MPExpression.h" + +@interface MPRangePath : NSObject + +#pragma mark Creation Methods + +- (instancetype)init; +- (instancetype)initWithLocation:(NSIndexPath *)location + length:(NSUInteger)length; +- (instancetype)initWithRange:(NSRange)aRange; + ++ (instancetype)emptyRangePath; ++ (instancetype)rangePathWithLocation:(NSIndexPath *)location + length:(NSUInteger)length; ++ (instancetype)rangePathWithRange:(NSRange)aRange; + +#pragma mark Properties + +@property (nonatomic, strong) NSIndexPath *location; +@property (nonatomic) NSUInteger length; + +- (NSIndexPath *)maxRangePath; +- (NSRange)rangeAtLastIndex; + +#pragma mark Working with Ranges + +- (BOOL)containsRangePath:(MPRangePath *)aRangePath; +- (BOOL)containsLocation:(NSIndexPath *)location; + +- (BOOL)isEqual:(id)object; +- (BOOL)isEqualToRangePath:(MPRangePath *)aRangePath; + +@end + +@interface MPExpression (MPRangeExtension) + +- (MPExpression *)subexpressionWithRangePath:(MPRangePath *)aRangePath; // If location points to expression (in function) nil is returned + +@end diff --git a/MathPad/MPRangePath.m b/MathPad/MPRangePath.m new file mode 100644 index 0000000..e498e01 --- /dev/null +++ b/MathPad/MPRangePath.m @@ -0,0 +1,153 @@ +// +// MPRange.m +// MathPad +// +// Created by Kim Wittenburg on 18.04.14. +// Copyright (c) 2014 Kim Wittenburg. All rights reserved. +// + +#import "MPRangePath.h" + +@implementation MPRangePath + +#pragma mark Creation Methods + +- (instancetype)init +{ + return [self initWithLocation:[[NSIndexPath alloc] init] + length:0]; +} + +- (instancetype)initWithLocation:(NSIndexPath *)location + length:(NSUInteger)length +{ + self = [super init]; + if (self) { + _location = location; + _length = length; + } + return self; +} + +- (instancetype)initWithRange:(NSRange)aRange +{ + return [self initWithLocation:[[NSIndexPath alloc] initWithIndex:aRange.location] + length:aRange.length]; +} + ++ (instancetype)emptyRangePath +{ + return [[self alloc] init]; +} + ++ (instancetype)rangePathWithLocation:(NSIndexPath *)location + length:(NSUInteger)length +{ + return [[self alloc] initWithLocation:location + length:length]; +} + ++ (instancetype)rangePathWithRange:(NSRange)aRange +{ + return [[self alloc] initWithRange:aRange]; +} + +#pragma mark Properties + +- (NSIndexPath *)maxRangePath +{ + NSUInteger lastIndex = [self.location indexAtPosition:self.location.length-1]; + NSUInteger newLastIndex = lastIndex + self.length; + return [[self.location indexPathByRemovingLastIndex] indexPathByAddingIndex:newLastIndex]; +} + +- (NSRange)rangeAtLastIndex +{ + return NSMakeRange([self.location indexAtPosition:self.location.length-1], self.length); +} + +#pragma mark Working with Ranges + +- (BOOL)containsRangePath:(MPRangePath *)aRangePath +{ + if (aRangePath.location.length < self.location.length) { + return NO; + } + // Compare indices (except the last one) + for (NSUInteger pos = 0; pos < self.location.length-1; pos++) { + NSUInteger selfIndex = [self.location indexAtPosition:pos]; + NSUInteger otherIndex = [aRangePath.location indexAtPosition:pos]; + if (selfIndex != otherIndex) { + return NO; + } + } + // Compare range at last index + NSUInteger selfIndex = [self.location indexAtPosition:self.location.length-1]; + NSUInteger otherIndex = [aRangePath.location indexAtPosition:self.location.length-1]; + if (aRangePath.location.length > self.location.length) { + return NSLocationInRange(otherIndex, self.rangeAtLastIndex); + } else { + return otherIndex >= selfIndex && NSMaxRange(aRangePath.rangeAtLastIndex) <= NSMaxRange(self.rangeAtLastIndex); + } +} + +- (BOOL)containsLocation:(NSIndexPath *)location +{ + return [self containsRangePath:[[MPRangePath alloc] initWithLocation:location length:0]]; +} + +- (BOOL)isEqual:(id)object +{ + if (self == object) { + return YES; + } + if (object == nil) { + return NO; + } + if (![object isKindOfClass:[MPRangePath class]]) { + return NO; + } + return [self isEqualToRangePath:(MPRangePath *)object]; +} + +- (BOOL)isEqualToRangePath:(MPRangePath *)aRangePath +{ + return [self.location isEqual:aRangePath.location] && self.length == aRangePath.length; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone +{ + MPRangePath *copy = [[MPRangePath allocWithZone:zone] initWithLocation:self.location.copy length:self.length]; + return copy; +} + +#pragma mark - NSCoding + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + return [self initWithLocation:[aDecoder decodeObjectForKey:@"location"] + length:[aDecoder decodeIntegerForKey:@"length"]]; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + [aCoder encodeObject:self.location forKey:@"location"]; + [aCoder encodeInteger:self.length forKey:@"length"]; +} + +@end + +@implementation MPExpression (MPRangeExtension) + +- (MPExpression *)subexpressionWithRangePath:(MPRangePath *)aRangePath +{ + MPExpression *targetExpression = [self symbolAtIndexPath:[aRangePath.location indexPathByRemovingLastIndex]]; + if (![targetExpression isKindOfClass:[MPExpression class]]) { + return nil; + } + return [targetExpression subexpressionWithRange:aRangePath.rangeAtLastIndex]; +} + +@end