Skip to content

Commit

Permalink
Adds support for stackrel using a subclass of MTLargeOperator. Closes k…
Browse files Browse the repository at this point in the history
  • Loading branch information
cupojoe committed Sep 8, 2019
1 parent be6f6ab commit 8bc8c80
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 11 deletions.
11 changes: 11 additions & 0 deletions iosMath/lib/MTMathList.h
Original file line number Diff line number Diff line change
Expand Up @@ -494,4 +494,15 @@ typedef NS_ENUM(NSInteger, MTColumnAlignment) {

@end

/** A subclass of MTLargeOperator, it adds no new functionality,
but allows to check if the atom if of said type when building a string
out of a math list
*/
@interface MTStackRel : MTLargeOperator

/// Convenience init to create the stackrel
- (instancetype) initWithBottom:(NSString*) bottom andTop:(MTMathList*) top NS_DESIGNATED_INITIALIZER;

@end

NS_ASSUME_NONNULL_END
14 changes: 14 additions & 0 deletions iosMath/lib/MTMathList.m
Original file line number Diff line number Diff line change
Expand Up @@ -1034,3 +1034,17 @@ - (id)copyWithZone:(NSZone *)zone
}

@end

#pragma mark - MTStackRel

@implementation MTStackRel : MTLargeOperator

/// Convenience init to create the stackrel
- (instancetype) initWithBottom:(NSString*) bottom andTop:(MTMathList*) top
{
self = [super initWithValue:bottom limits:YES];
self.superScript = top;
return self;
}

@end
28 changes: 19 additions & 9 deletions iosMath/lib/MTMathListBuilder.m
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,11 @@ - (MTMathAtom*) atomForCommand:(NSString*) command
mathColorbox.colorString = [self readColor];
mathColorbox.innerList = [self buildInternal:true];
return mathColorbox;
} else if ([command isEqualToString:@"stackrel"]) {
MTMathList* top = [self buildInternal:YES];
MTMathList* bottom = [self buildInternal:YES];
MTLargeOperator* stack = [[MTStackRel alloc] initWithBottom:bottom.stringValue andTop:top];
return stack;
} else {
NSString* errorMessage = [NSString stringWithFormat:@"Invalid command \\%@", command];
[self setError:MTParseErrorInvalidCommand message:errorMessage];
Expand Down Expand Up @@ -842,15 +847,20 @@ + (NSString *)mathListToString:(MTMathList *)ml
MTAccent* accent = (MTAccent*) atom;
[str appendFormat:@"\\%@{%@}", [MTMathAtomFactory accentName:accent], [self mathListToString:accent.innerList]];
} else if (atom.type == kMTMathAtomLargeOperator) {
MTLargeOperator* op = (MTLargeOperator*) atom;
NSString* command = [MTMathAtomFactory latexSymbolNameForAtom:atom];
MTLargeOperator* originalOp = (MTLargeOperator*) [MTMathAtomFactory atomForLatexSymbolName:command];
[str appendFormat:@"\\%@ ", command];
if (originalOp.limits != op.limits) {
if (op.limits) {
[str appendString:@"\\limits "];
} else {
[str appendString:@"\\nolimits "];
if ([atom isKindOfClass:[MTStackRel class]]) {
[str appendFormat:@"\\stackrel{%@}{%@}", [self mathListToString:atom.superScript], atom.nucleus];
continue;
} else {
MTLargeOperator* op = (MTLargeOperator*) atom;
NSString* command = [MTMathAtomFactory latexSymbolNameForAtom:atom];
MTLargeOperator* originalOp = (MTLargeOperator*) [MTMathAtomFactory atomForLatexSymbolName:command];
[str appendFormat:@"\\%@ ", command];
if (originalOp.limits != op.limits) {
if (op.limits) {
[str appendString:@"\\limits "];
} else {
[str appendString:@"\\nolimits "];
}
}
}
} else if (atom.type == kMTMathAtomSpace) {
Expand Down
8 changes: 6 additions & 2 deletions iosMathExample/example/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ - (void)viewDidLoad
// set the size of the content view
// Disable horizontal scrolling.
[self setEqualWidths:contentView andView:self.scrollView];
[self setHeight:4350 forView:contentView];
[self setHeight:4520 forView:contentView];


// Demo formulae
Expand Down Expand Up @@ -177,7 +177,7 @@ - (void)viewDidLoad
"\\end{cases}" withHeight:60];

self.demoLabels[21] = [self createMathLabel:@"\\color{#ff3333}{c}\\color{#9933ff}{o}\\color{#ff0080}{l}+\\color{#99ff33}{\\frac{\\color{#ff99ff}{o}}{\\color{#990099}{r}}}-\\color{#33ffff}{\\sqrt[\\color{#3399ff}{e}]{\\color{#3333ff}{d}}}" withHeight:60];


for (NSUInteger i = 1; i < self.demoLabels.count; i++) {
self.demoLabels[i].fontSize = 15;
Expand Down Expand Up @@ -320,6 +320,10 @@ - (void)viewDidLoad
"\\colorbox{#00aaff}{c} & \\colorbox{#f0f0f0}{d}"
"\\end{pmatrix}}"
withHeight:70];

// Test stackrel
self.labels[48] = [self createMathLabel:@"\\lim_{x \\to 0} \\frac{\\ln{x}}{x^{2} - 1} \\stackrel{H}{=} \\lim_{x \\to 0} \\frac{\\frac{1}{x}}{2x}" withHeight:90];
self.labels[49] = [self createMathLabel:@"\\stackrel{up}{bottom}" withHeight:60];

for (NSUInteger i = 1; i < self.labels.count; i++) {
[self addLabelWithIndex:i inArray:self.labels toView:contentView];
Expand Down
19 changes: 19 additions & 0 deletions iosMathTests/MTMathListBuilderTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -1385,4 +1385,23 @@ - (void) testNoLimits
latex = [MTMathListBuilder mathListToString:list];
XCTAssertEqualObjects(latex, @"\\sum \\nolimits ", @"%@", desc);
}

- (void) testStackrel
{
// L'hopital rule
NSString *str = @"\\stackrel{H}{=}";
MTMathList* list = [MTMathListBuilder buildFromString:str];
NSString* desc = [NSString stringWithFormat:@"Error for string:%@", str];

XCTAssertNotNil(list, @"%@", desc);
XCTAssertEqualObjects(@(list.atoms.count), @1, @"%@", desc);
MTLargeOperator* op = list.atoms[0];
XCTAssertEqual(op.type, kMTMathAtomLargeOperator, @"%@", desc);
XCTAssertTrue(op.limits);
XCTAssertTrue([op isKindOfClass:[MTStackRel class]]);

// convert it back to latex
NSString* latex = [MTMathListBuilder mathListToString:list];
XCTAssertEqualObjects(latex, @"\\stackrel{H}{=}", @"%@", desc);
}
@end

0 comments on commit 8bc8c80

Please sign in to comment.