Corrected MPExpression -itemAtIndex:referenceFrame:MPSymbolReferenceFrame
Corrected Deformed Number Format Added "arcsin", "arccos", "arctan", "lg", "log", "ln" Elementary Functions
This commit is contained in:
@@ -39,17 +39,21 @@
|
|||||||
} else if ([function isEqualToString:@"tan"]) {
|
} else if ([function isEqualToString:@"tan"]) {
|
||||||
func = &tan;
|
func = &tan;
|
||||||
takesArc = YES;
|
takesArc = YES;
|
||||||
} else if ([function isEqualToString:@"asin"]) {
|
} else if ([function isEqualToString:@"asin"] || [function isEqualToString:@"arcsin"]) {
|
||||||
func = &asin;
|
func = &asin;
|
||||||
returnsArc = YES;
|
returnsArc = YES;
|
||||||
} else if ([function isEqualToString:@"acos"]) {
|
} else if ([function isEqualToString:@"acos"] || [function isEqualToString:@"arccos"]) {
|
||||||
func = &acos;
|
func = &acos;
|
||||||
returnsArc = YES;
|
returnsArc = YES;
|
||||||
} else if ([function isEqualToString:@"atan"]) {
|
} else if ([function isEqualToString:@"atan"] || [function isEqualToString:@"arctan"]) {
|
||||||
func = &atan;
|
func = &atan;
|
||||||
returnsArc = YES;
|
returnsArc = YES;
|
||||||
|
} else if ([function isEqualToString:@"lg"] || [function isEqualToString:@"log"]) {
|
||||||
|
func = &log10;
|
||||||
|
} else if ([function isEqualToString:@"ln"]) {
|
||||||
|
func = &log;
|
||||||
} else {
|
} else {
|
||||||
NSAssert(true, @"function must be one of (sin, cos, tan, asin, acos, atan).");
|
NSAssert(true, @"function must be one of (sin, cos, tan, asin, acos, atan, lg, log, ln).");
|
||||||
}
|
}
|
||||||
[self setFunction:func
|
[self setFunction:func
|
||||||
takesArcValue:takesArc
|
takesArcValue:takesArc
|
||||||
|
|||||||
@@ -269,18 +269,17 @@ NSString *const MPIllegalElementExceptionElementKey = @"MPIllegalElementExceptio
|
|||||||
|
|
||||||
case MPSymbolReferenceFrame:
|
case MPSymbolReferenceFrame:
|
||||||
{
|
{
|
||||||
NSUInteger location = 0;
|
NSUInteger offsetInElement;
|
||||||
NSUInteger elementIndex = 0;
|
NSUInteger elementIndex = [self convertIndex:anIndex
|
||||||
id <MPExpressionElement> element = nil;
|
fromReferenceFrame:MPSymbolReferenceFrame
|
||||||
while (location < anIndex) {
|
toReferenceFrame:MPElementReferenceFrame
|
||||||
element = _elements[elementIndex++];
|
offset:&offsetInElement];
|
||||||
location += element.length;
|
id<MPExpressionElement> element = [self elementAtIndex:elementIndex];
|
||||||
}
|
if ([element isFunction]) {
|
||||||
if (location == anIndex && element.isFunction) {
|
|
||||||
return element;
|
return element;
|
||||||
|
} else {
|
||||||
|
return [((NSString *)element) substringWithRange:NSMakeRange(offsetInElement, 1)];
|
||||||
}
|
}
|
||||||
NSUInteger indexInString = location - element.length + anIndex;
|
|
||||||
return [((NSString *)element) substringWithRange:NSMakeRange(indexInString, 1)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case MPTokenReferenceFrame:
|
case MPTokenReferenceFrame:
|
||||||
|
|||||||
@@ -259,8 +259,9 @@
|
|||||||
// Set the text matrix
|
// Set the text matrix
|
||||||
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
|
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
|
||||||
|
|
||||||
// Track the x position
|
// Track the x position and the bounds of the last element
|
||||||
CGFloat x = 0;
|
CGFloat x = 0;
|
||||||
|
NSRect lastElementBounds = NSMakeRect(0, kMPEmptyBoxYOrigin, kMPEmptyBoxWidth, kMPEmptyBoxHeight);
|
||||||
|
|
||||||
for (NSUInteger index = 0; index < self.expression.countElements; index++) {
|
for (NSUInteger index = 0; index < self.expression.countElements; index++) {
|
||||||
// The current element
|
// The current element
|
||||||
@@ -279,17 +280,16 @@
|
|||||||
CTLineDraw(line, context);
|
CTLineDraw(line, context);
|
||||||
|
|
||||||
CFRelease(line);
|
CFRelease(line);
|
||||||
|
|
||||||
if (index < self.expression.countElements-1 && [[self.expression elementAtIndex:index+1] isKindOfClass:[MPPowerFunction class]]) {
|
|
||||||
MPPowerFunctionLayout *layout = (MPPowerFunctionLayout *)[self childLayoutAtIndex:index+1];
|
|
||||||
layout.baseBounds = elementBounds;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Let the child layout draw itself
|
// Let the child layout draw itself
|
||||||
MPLayout *layout = [self childLayoutAtIndex:index];
|
MPLayout *layout = [self childLayoutAtIndex:index];
|
||||||
|
if ([layout isKindOfClass:[MPPowerFunctionLayout class]]) {
|
||||||
|
((MPPowerFunctionLayout *)layout).baseBounds = lastElementBounds;
|
||||||
|
}
|
||||||
[layout drawAtPoint:NSMakePoint(x, 0)];
|
[layout drawAtPoint:NSMakePoint(x, 0)];
|
||||||
}
|
}
|
||||||
x += elementBounds.size.width;
|
x += elementBounds.size.width;
|
||||||
|
lastElementBounds = elementBounds;
|
||||||
}
|
}
|
||||||
CGContextRestoreGState(context);
|
CGContextRestoreGState(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,9 +49,9 @@
|
|||||||
NSString *regexStringFormat = @"\\A(?:"
|
NSString *regexStringFormat = @"\\A(?:"
|
||||||
@"([\\*∙⋅])|"
|
@"([\\*∙⋅])|"
|
||||||
@"([+-](?:\\s*[+-])*)|"
|
@"([+-](?:\\s*[+-])*)|"
|
||||||
@"((?:\\d+%@(?!\\d+))|(?:(?:\\d*%@){2,}\\d*)|%@)|" // Substitute with decimal separator 3 times
|
@"((?:\\d+%@(?!\\d+))|(?:(?:\\d*%@){2,}\\d*)|%@(?!\\d+))|" // Substitute with decimal separator 3 times
|
||||||
@"((?:\\d+(?:%@\\d+)?)|(?:%@\\d+))|" // Substitute with decimal separator 2 times
|
@"((?:\\d+(?:%@\\d+)?)|(?:%@\\d+))|" // Substitute with decimal separator 2 times
|
||||||
@"(sin|cos|tan|asin|acos|atan)|"
|
@"(sin|cos|tan|asin|arcsin|acos|arccos|atan|arctan|lg|log|ln)|"
|
||||||
@"([A-Za-z])|"
|
@"([A-Za-z])|"
|
||||||
@"(!)|"
|
@"(!)|"
|
||||||
@"(=)|"
|
@"(=)|"
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#import "MPParenthesisFunction.h"
|
#import "MPParenthesisFunction.h"
|
||||||
#import "MPFractionFunction.h"
|
#import "MPFractionFunction.h"
|
||||||
|
|
||||||
|
#import "MPToken.h"
|
||||||
#import "MPRangePath.h"
|
#import "MPRangePath.h"
|
||||||
#import "MPMathRules.h"
|
#import "MPMathRules.h"
|
||||||
|
|
||||||
@@ -648,6 +649,10 @@
|
|||||||
[self insertParenthesisFunction:nil];
|
[self insertParenthesisFunction:nil];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ([characters isEqualToString:@")"]) {
|
||||||
|
[self insertClosingParenthesis];
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (theEvent.keyCode == 10) {
|
if (theEvent.keyCode == 10) {
|
||||||
[self insertPowerFunction];
|
[self insertPowerFunction];
|
||||||
return;
|
return;
|
||||||
@@ -692,6 +697,29 @@
|
|||||||
self.selection = MPMakeRangePath([[functionPath indexPathByAddingIndex:0] indexPathByAddingIndex:0], self.selection.length);
|
self.selection = MPMakeRangePath([[functionPath indexPathByAddingIndex:0] indexPathByAddingIndex:0], self.selection.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)insertClosingParenthesis
|
||||||
|
{
|
||||||
|
if (self.selection.length > 0) {
|
||||||
|
[self insertParenthesisFunction:self];
|
||||||
|
} else {
|
||||||
|
NSIndexPath *currentPath = [[self.selection.location indexPathByRemovingLastIndex] indexPathByRemovingLastIndex];
|
||||||
|
while (currentPath.length > 0) {
|
||||||
|
id element = [self.expressionStorage elementAtIndexPath:currentPath];
|
||||||
|
if ([element isKindOfClass:[MPParenthesisFunction class]]) {
|
||||||
|
MPExpression *targetExpression = [self.expressionStorage elementAtIndexPath:[currentPath indexPathByRemovingLastIndex]];
|
||||||
|
NSUInteger selectedIndex = currentPath.lastIndex + 1;
|
||||||
|
selectedIndex = [targetExpression convertIndex:selectedIndex
|
||||||
|
fromReferenceFrame:MPElementReferenceFrame
|
||||||
|
toReferenceFrame:MPSymbolReferenceFrame];
|
||||||
|
self.selection = MPMakeRangePath([currentPath indexPathByReplacingLastIndexWithIndex:selectedIndex], 0);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
currentPath = [[currentPath indexPathByRemovingLastIndex] indexPathByRemovingLastIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)insertPowerFunction
|
- (void)insertPowerFunction
|
||||||
{
|
{
|
||||||
MPExpression *selectedElementsExpression = [self.expressionStorage subexpressionWithRangePath:self.selection
|
MPExpression *selectedElementsExpression = [self.expressionStorage subexpressionWithRangePath:self.selection
|
||||||
@@ -712,6 +740,41 @@
|
|||||||
|
|
||||||
- (void)insertFractionFunction
|
- (void)insertFractionFunction
|
||||||
{
|
{
|
||||||
|
if (self.selection.length == 0) {
|
||||||
|
MPExpression *targetExpression = [self.expressionStorage elementAtIndexPath:[self.selection.location indexPathByRemovingLastIndex]];
|
||||||
|
NSInteger index = self.selection.location.lastIndex;
|
||||||
|
NSRange nominatorSymbols = NSMakeRange(index, 0);
|
||||||
|
while (--index >= 0) {
|
||||||
|
id<MPExpressionElement> symbol = [targetExpression symbolAtIndex:index];
|
||||||
|
if ([symbol isString]) {
|
||||||
|
NSUInteger tokenIndex = [targetExpression convertIndex:index
|
||||||
|
fromReferenceFrame:MPSymbolReferenceFrame
|
||||||
|
toReferenceFrame:MPTokenReferenceFrame];
|
||||||
|
id<MPToken> token = [targetExpression tokenAtIndex:tokenIndex];
|
||||||
|
if (token.tokenType == MPNumberToken || token.tokenType == MPVariableToken || token.tokenType == MPElementaryFunctionToken) {
|
||||||
|
nominatorSymbols.location--;
|
||||||
|
nominatorSymbols.length++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (nominatorSymbols.length == 0) {
|
||||||
|
nominatorSymbols.location--;
|
||||||
|
nominatorSymbols.length++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MPExpression *nominatorExpression = [targetExpression subexpressionWithRange:nominatorSymbols
|
||||||
|
referenceFrame:MPSymbolReferenceFrame];
|
||||||
|
MPFractionFunction *function = [[MPFractionFunction alloc] init];
|
||||||
|
function.nominatorExpression = nominatorExpression;
|
||||||
|
[targetExpression replaceItemsInRange:nominatorSymbols referenceFrame:MPSymbolReferenceFrame withElements:@[function]];
|
||||||
|
NSUInteger functionElementIndex = [targetExpression convertIndex:nominatorSymbols.location
|
||||||
|
fromReferenceFrame:MPSymbolReferenceFrame
|
||||||
|
toReferenceFrame:MPElementReferenceFrame];
|
||||||
|
NSUInteger selectedSubexpression = nominatorSymbols.length == 0 ? 0 : 1;
|
||||||
|
self.selection = MPMakeRangePath([[[self.selection.location indexPathByReplacingLastIndexWithIndex:functionElementIndex] indexPathByAddingIndex:selectedSubexpression] indexPathByAddingIndex:0], 0);
|
||||||
|
} else {
|
||||||
MPExpression *selectedElementsExpression = [self.expressionStorage subexpressionWithRangePath:self.selection
|
MPExpression *selectedElementsExpression = [self.expressionStorage subexpressionWithRangePath:self.selection
|
||||||
referenceFrame:MPSymbolReferenceFrame];
|
referenceFrame:MPSymbolReferenceFrame];
|
||||||
MPFractionFunction *function = [[MPFractionFunction alloc] init];
|
MPFractionFunction *function = [[MPFractionFunction alloc] init];
|
||||||
@@ -726,6 +789,7 @@
|
|||||||
NSIndexPath *functionPath = [self.selection.location indexPathByReplacingLastIndexWithIndex:functionElementIndex];
|
NSIndexPath *functionPath = [self.selection.location indexPathByReplacingLastIndexWithIndex:functionElementIndex];
|
||||||
self.selection = MPMakeRangePath([[functionPath indexPathByAddingIndex:0] indexPathByAddingIndex:0], 0);
|
self.selection = MPMakeRangePath([[functionPath indexPathByAddingIndex:0] indexPathByAddingIndex:0], 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)insertNewline:(id)sender
|
- (void)insertNewline:(id)sender
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
- (NSIndexSet *)indexesOfRemainingChildren
|
- (NSIndexSet *)indexesOfRemainingChildren
|
||||||
{
|
{
|
||||||
return [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 1)];
|
return [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSPoint)offsetOfChildLayoutAtIndex:(NSUInteger)index
|
- (NSPoint)offsetOfChildLayoutAtIndex:(NSUInteger)index
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
- (NSFont *)specialFontWithSize:(CGFloat)size
|
- (NSFont *)specialFontWithSize:(CGFloat)size
|
||||||
{
|
{
|
||||||
return [NSFont fontWithName:@"CMU Sans Serif Oblique"
|
return [NSFont fontWithName:@"CMU Serif Italic"
|
||||||
size:size];
|
size:size];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user