@@ -10,7 +10,7 @@ namespace CSharpMath.CoreTests {
10
10
public class LaTeXParserTest {
11
11
public static MathList ParseLaTeX ( string latex ) {
12
12
var builder = new LaTeXParser ( latex ) ;
13
- if ( builder . Build ( ) is { } mathList ) {
13
+ if ( builder . Build ( ) is { } mathList ) {
14
14
Assert . Null ( builder . Error ) ;
15
15
return mathList ;
16
16
} else throw new Xunit . Sdk . NotNullException ( ) ;
@@ -419,6 +419,47 @@ public void TestMatrix(string env, string left, string right, string leftOutput,
419
419
Assert . Equal ( $@ "{ leftOutput } \begin{{matrix}}x&y\\ z&w\end{{matrix}}{ rightOutput } ",
420
420
LaTeXParser . MathListToLaTeX ( list ) . ToString ( ) ) ;
421
421
}
422
+ [ Theory ]
423
+ [ InlineData ( @"\color{red}\begin{pmatrix}1&2\\3&4\end{pmatrix}" ) ]
424
+ [ InlineData ( @"\color{red}\begin{pmatrix}{1}&2\\3&{4}\end{pmatrix}" ) ]
425
+ [ InlineData ( @"\color{red}{\begin{pmatrix}1&2\\3&4\end{pmatrix}}" ) ]
426
+ [ InlineData ( @"\color{red}{{\begin{pmatrix}1&2\\3&4\end{pmatrix}}}" ) ]
427
+ [ InlineData ( @"\color{red}\left(\begin{matrix}1&2\\3&4\end{matrix}\right)" ) ]
428
+ [ InlineData ( @"\color{red}\left( \begin{matrix}1&2\\ 3&4\end{matrix}\right) " ) ]
429
+ [ InlineData ( @"\color{red}{\left( \begin{matrix}1&2\\ 3&4\end{matrix}\right) }" ) ]
430
+ [ InlineData ( @"\color{red}{{\left( \begin{matrix}1&2\\ 3&4\end{matrix}\right) }}" ) ]
431
+ public void TestRedMatrix ( string input ) {
432
+ var list = ParseLaTeX ( input ) ;
433
+ Assert . Collection ( list , CheckAtom < Color > ( "" , color => {
434
+ Assert . Equal ( new Structures . Color ( 255 , 0 , 0 ) , color . Colour ) ;
435
+ Assert . Collection ( color . InnerList ,
436
+ CheckAtom < Inner > ( "" , inner => {
437
+ Assert . Equal ( new Boundary ( "(" ) , inner . LeftBoundary ) ;
438
+ Assert . Equal ( new Boundary ( ")" ) , inner . RightBoundary ) ;
439
+ Assert . Collection ( inner . InnerList ,
440
+ CheckAtom < Table > ( "" , table => {
441
+ Assert . Equal ( "matrix" , table . Environment ) ;
442
+ Assert . Equal ( 0 , table . InterRowAdditionalSpacing ) ;
443
+ Assert . Equal ( 18 , table . InterColumnSpacing ) ;
444
+ Assert . Equal ( 2 , table . NRows ) ;
445
+ Assert . Equal ( 2 , table . NColumns ) ;
446
+ for ( int col = 0 ; col < 2 ; col ++ ) {
447
+ Assert . Equal ( ColumnAlignment . Center , table . GetAlignment ( col ) ) ;
448
+ for ( int row = 0 ; row < 2 ; row ++ ) {
449
+ Assert . Collection ( table . Cells [ row ] [ col ] ,
450
+ CheckAtom < Style > ( "" , style => Assert . Equal ( LineStyle . Text , style . LineStyle ) ) ,
451
+ atom => Assert . IsType < Number > ( atom )
452
+ ) ;
453
+ }
454
+ }
455
+ } )
456
+ ) ;
457
+ } )
458
+ ) ;
459
+ } ) ) ;
460
+ Assert . Equal ( @"\color{red}{\left( \begin{matrix}1&2\\ 3&4\end{matrix}\right) }" ,
461
+ LaTeXParser . MathListToLaTeX ( list ) . ToString ( ) ) ;
462
+ }
422
463
423
464
[ Fact ]
424
465
public void TestDeterminant ( ) {
@@ -454,6 +495,21 @@ IEnumerable<Action<MathAtom>> Checkers() {
454
495
Assert . Equal ( @"\left| \begin{matrix}\sin (x)&\cos (x)\\ -\cos (x)&\sin (x)\end{matrix}\right| =1" , LaTeXParser . MathListToLaTeX ( list ) . ToString ( ) ) ;
455
496
}
456
497
498
+ [ Fact ]
499
+ public void TestDefaultEmptyTable ( ) {
500
+ var list = ParseLaTeX ( @"\\" ) ;
501
+ var table = Assert . IsType < Table > ( Assert . Single ( list ) ) ;
502
+ CheckAtom < Table > ( "" ) ( table ) ;
503
+ Assert . Null ( table . Environment ) ;
504
+ Assert . Equal ( 1 , table . InterRowAdditionalSpacing ) ;
505
+ Assert . Equal ( 0 , table . InterColumnSpacing ) ;
506
+ Assert . Equal ( 2 , table . NRows ) ;
507
+ Assert . Equal ( 1 , table . NColumns ) ;
508
+ Assert . Equal ( ColumnAlignment . Left , table . GetAlignment ( 0 ) ) ;
509
+ Assert . Equal ( ColumnAlignment . Center , table . GetAlignment ( 1 ) ) ;
510
+ Assert . Collection ( table . Cells , row0 => Assert . Empty ( Assert . Single ( row0 ) ) , Assert . Empty ) ;
511
+ Assert . Equal ( @"\\ " , LaTeXParser . MathListToLaTeX ( list ) . ToString ( ) ) ;
512
+ }
457
513
[ Fact ]
458
514
public void TestDefaultTable ( ) {
459
515
var list = ParseLaTeX ( @"x \\ y" ) ;
@@ -473,6 +529,181 @@ public void TestDefaultTable() {
473
529
Assert . Equal ( @"x\\ y" , LaTeXParser . MathListToLaTeX ( list ) . ToString ( ) ) ;
474
530
}
475
531
532
+ [ Theory ]
533
+ [ InlineData ( @"\left(x\\\right)" ) ]
534
+ [ InlineData ( @"\left(x \\ \right)" ) ]
535
+ [ InlineData ( @"\left( x\\ \right)" ) ]
536
+ [ InlineData ( @"\left( x\\ \right) " ) ]
537
+ [ InlineData ( @"\left({x\\}\right) " ) ]
538
+ [ InlineData ( @"\left({{x\\}}\right) " ) ]
539
+ public void TestDefaultTableInInner ( string input ) {
540
+ var list = ParseLaTeX ( input ) ;
541
+ CheckAtom < Inner > ( "" , inner => {
542
+ Assert . Equal ( new Boundary ( "(" ) , inner . LeftBoundary ) ;
543
+ Assert . Equal ( new Boundary ( ")" ) , inner . RightBoundary ) ;
544
+ CheckAtom < Table > ( "" , table => {
545
+ Assert . Null ( table . Environment ) ;
546
+ Assert . Equal ( 1 , table . InterRowAdditionalSpacing ) ;
547
+ Assert . Equal ( 0 , table . InterColumnSpacing ) ;
548
+ Assert . Equal ( 2 , table . NRows ) ;
549
+ Assert . Equal ( 1 , table . NColumns ) ;
550
+ Assert . Equal ( ColumnAlignment . Left , table . GetAlignment ( 0 ) ) ;
551
+ Assert . IsType < Variable > ( Assert . Single ( table . Cells [ 0 ] [ 0 ] ) ) ;
552
+ Assert . Empty ( table . Cells [ 1 ] [ 0 ] ) ;
553
+ } ) ( Assert . Single ( inner . InnerList ) ) ;
554
+ } ) ( Assert . Single ( list ) ) ;
555
+ Assert . Equal ( @"\left( x\\ \right) " , LaTeXParser . MathListToLaTeX ( list ) . ToString ( ) ) ;
556
+ }
557
+ [ Theory ]
558
+ [ InlineData ( @"\left(\\\right)" ) ]
559
+ [ InlineData ( @"\left( \\ \right) " ) ]
560
+ [ InlineData ( @"\left({\\}\right) " ) ]
561
+ [ InlineData ( @"\left({{\\}}\right) " ) ]
562
+ public void TestEmptyTableInInner ( string input ) {
563
+ var list = ParseLaTeX ( input ) ;
564
+ CheckAtom < Inner > ( "" , inner => {
565
+ Assert . Equal ( new Boundary ( "(" ) , inner . LeftBoundary ) ;
566
+ Assert . Equal ( new Boundary ( ")" ) , inner . RightBoundary ) ;
567
+ CheckAtom < Table > ( "" , table => {
568
+ Assert . Null ( table . Environment ) ;
569
+ Assert . Equal ( 1 , table . InterRowAdditionalSpacing ) ;
570
+ Assert . Equal ( 0 , table . InterColumnSpacing ) ;
571
+ Assert . Equal ( 2 , table . NRows ) ;
572
+ Assert . Equal ( 1 , table . NColumns ) ;
573
+ for ( int col = 0 ; col < 1 ; col ++ ) {
574
+ Assert . Equal ( ColumnAlignment . Left , table . GetAlignment ( col ) ) ;
575
+ for ( int row = 0 ; row < 2 ; row ++ ) {
576
+ Assert . Empty ( table . Cells [ row ] [ col ] ) ;
577
+ }
578
+ }
579
+ } ) ( Assert . Single ( inner . InnerList ) ) ;
580
+ } ) ( Assert . Single ( list ) ) ;
581
+ Assert . Equal ( @"\left( \\ \right) " , LaTeXParser . MathListToLaTeX ( list ) . ToString ( ) ) ;
582
+ }
583
+ [ Theory ]
584
+ [ InlineData ( @"x\\1\left(2\right)3\\x" ) ]
585
+ [ InlineData ( @"x\\ 1\left( 2\right) 3\\ x" ) ]
586
+ public void TestInnerInTable ( string input ) {
587
+ var list = ParseLaTeX ( input ) ;
588
+ CheckAtom < Table > ( "" , table => {
589
+ Assert . Null ( table . Environment ) ;
590
+ Assert . Equal ( 1 , table . InterRowAdditionalSpacing ) ;
591
+ Assert . Equal ( 0 , table . InterColumnSpacing ) ;
592
+ Assert . Equal ( 3 , table . NRows ) ;
593
+ Assert . Equal ( 1 , table . NColumns ) ;
594
+ for ( int col = 0 ; col < 1 ; col ++ ) {
595
+ Assert . Equal ( ColumnAlignment . Left , table . GetAlignment ( col ) ) ;
596
+ for ( int row = 0 ; row < 3 ; row ++ ) {
597
+ if ( row == 1 )
598
+ Assert . Collection (
599
+ table . Cells [ row ] [ col ] ,
600
+ CheckAtom < Number > ( "1" ) ,
601
+ CheckAtom < Inner > ( "" , inner => {
602
+ Assert . Equal ( new Boundary ( "(" ) , inner . LeftBoundary ) ;
603
+ Assert . Collection ( inner . InnerList , CheckAtom < Number > ( "2" ) ) ;
604
+ Assert . Equal ( new Boundary ( ")" ) , inner . RightBoundary ) ;
605
+ } ) ,
606
+ CheckAtom < Number > ( "3" )
607
+ ) ;
608
+ else
609
+ Assert . Collection (
610
+ table . Cells [ row ] [ col ] ,
611
+ CheckAtom < Variable > ( "x" )
612
+ ) ;
613
+ }
614
+ }
615
+ } ) ( Assert . Single ( list ) ) ;
616
+ Assert . Equal ( @"x\\ 1\left( 2\right) 3\\ x" , LaTeXParser . MathListToLaTeX ( list ) . ToString ( ) ) ;
617
+ }
618
+ [ Theory ]
619
+ [ InlineData ( @"1\\2\left(3\begin{array}{ll}4&\left[5\\6\right]\\\left\{7\begin{cases}8\\9\end{cases}0\right\}a\end{array}b\right)c\\d" , 0 ) ]
620
+ [ InlineData ( @"1\\ 2\left( 3\begin{array}{ll}4&\left[ 5\\ 6\right] \\ \left\{ 7\left\{ \, \begin{array}{l}\textstyle 8\\ \textstyle 9\end{array}\right. 0\right\} a\end{array}b\right) c\\ d" , 1 ) ]
621
+ public void TestTablesAndInners ( string input , float casesInterRowAdditionalSpacing ) {
622
+ var list = ParseLaTeX ( input ) ;
623
+ CheckAtom < Table > ( "" , table => {
624
+ Assert . Null ( table . Environment ) ;
625
+ Assert . Equal ( 1 , table . InterRowAdditionalSpacing ) ;
626
+ Assert . Equal ( 0 , table . InterColumnSpacing ) ;
627
+ Assert . Equal ( 3 , table . NRows ) ;
628
+ Assert . Equal ( 1 , table . NColumns ) ;
629
+ Assert . Equal ( ColumnAlignment . Left , table . GetAlignment ( 0 ) ) ;
630
+ Assert . Equal ( ColumnAlignment . Center , table . GetAlignment ( 1 ) ) ;
631
+ Assert . Collection ( table . Cells [ 0 ] [ 0 ] , CheckAtom < Number > ( "1" ) ) ;
632
+ Assert . Collection ( table . Cells [ 1 ] [ 0 ] ,
633
+ CheckAtom < Number > ( "2" ) ,
634
+ CheckAtom < Inner > ( "" , inner => {
635
+ Assert . Equal ( new Boundary ( "(" ) , inner . LeftBoundary ) ;
636
+ Assert . Equal ( new Boundary ( ")" ) , inner . RightBoundary ) ;
637
+ Assert . Collection ( inner . InnerList ,
638
+ CheckAtom < Number > ( "3" ) ,
639
+ CheckAtom < Table > ( "" , array => {
640
+ Assert . Equal ( "array" , array . Environment ) ;
641
+ Assert . Equal ( 1 , array . InterRowAdditionalSpacing ) ;
642
+ Assert . Equal ( 18 , array . InterColumnSpacing ) ;
643
+ Assert . Equal ( 2 , array . NRows ) ;
644
+ Assert . Equal ( 2 , array . NColumns ) ;
645
+ Assert . Equal ( ColumnAlignment . Left , array . GetAlignment ( 0 ) ) ;
646
+ Assert . Equal ( ColumnAlignment . Left , array . GetAlignment ( 1 ) ) ;
647
+ Assert . Equal ( ColumnAlignment . Center , array . GetAlignment ( 2 ) ) ;
648
+ Assert . Collection ( array . Cells [ 0 ] [ 0 ] , CheckAtom < Number > ( "4" ) ) ;
649
+ Assert . Collection ( array . Cells [ 0 ] [ 1 ] , CheckAtom < Inner > ( "" , inner56 => {
650
+ Assert . Equal ( new Boundary ( "[" ) , inner56 . LeftBoundary ) ;
651
+ Assert . Equal ( new Boundary ( "]" ) , inner56 . RightBoundary ) ;
652
+ Assert . Collection ( inner56 . InnerList , CheckAtom < Table > ( "" , table56 => {
653
+ Assert . Null ( table56 . Environment ) ;
654
+ Assert . Equal ( 1 , table56 . InterRowAdditionalSpacing ) ;
655
+ Assert . Equal ( 0 , table56 . InterColumnSpacing ) ;
656
+ Assert . Equal ( 2 , table56 . NRows ) ;
657
+ Assert . Equal ( 1 , table56 . NColumns ) ;
658
+ Assert . Equal ( ColumnAlignment . Left , table56 . GetAlignment ( 0 ) ) ;
659
+ Assert . Equal ( ColumnAlignment . Center , table56 . GetAlignment ( 1 ) ) ;
660
+ Assert . Collection ( table56 . Cells [ 0 ] [ 0 ] , CheckAtom < Number > ( "5" ) ) ;
661
+ Assert . Collection ( table56 . Cells [ 1 ] [ 0 ] , CheckAtom < Number > ( "6" ) ) ;
662
+ } ) ) ;
663
+ } ) ) ;
664
+ Assert . Collection ( array . Cells [ 1 ] [ 0 ] ,
665
+ CheckAtom < Inner > ( "" , innerCases => {
666
+ Assert . Equal ( new Boundary ( "{" ) , innerCases . LeftBoundary ) ;
667
+ Assert . Equal ( new Boundary ( "}" ) , innerCases . RightBoundary ) ;
668
+ Assert . Collection ( innerCases . InnerList ,
669
+ CheckAtom < Number > ( "7" ) ,
670
+ CheckAtom < Inner > ( "" , innerCasesInner => {
671
+ Assert . Equal ( new Boundary ( "{" ) , innerCasesInner . LeftBoundary ) ;
672
+ Assert . Equal ( Boundary . Empty , innerCasesInner . RightBoundary ) ;
673
+ Assert . Collection ( innerCasesInner . InnerList ,
674
+ CheckAtom < Space > ( "" , space => Assert . Equal ( 3 , space . Length ) ) ,
675
+ CheckAtom < Table > ( "" , tableCases => {
676
+ Assert . Equal ( "array" , tableCases . Environment ) ;
677
+ Assert . Equal ( casesInterRowAdditionalSpacing , tableCases . InterRowAdditionalSpacing ) ;
678
+ Assert . Equal ( 18 , tableCases . InterColumnSpacing ) ;
679
+ Assert . Equal ( 2 , tableCases . NRows ) ;
680
+ Assert . Equal ( 1 , tableCases . NColumns ) ;
681
+ Assert . Equal ( ColumnAlignment . Left , tableCases . GetAlignment ( 0 ) ) ;
682
+ Assert . Equal ( ColumnAlignment . Center , tableCases . GetAlignment ( 1 ) ) ;
683
+ Assert . Collection ( tableCases . Cells [ 0 ] [ 0 ] ,
684
+ CheckAtom < Style > ( "" , style => Assert . Equal ( LineStyle . Text , style . LineStyle ) ) ,
685
+ CheckAtom < Number > ( "8" ) ) ;
686
+ Assert . Collection ( tableCases . Cells [ 1 ] [ 0 ] ,
687
+ CheckAtom < Style > ( "" , style => Assert . Equal ( LineStyle . Text , style . LineStyle ) ) ,
688
+ CheckAtom < Number > ( "9" ) ) ;
689
+ } )
690
+ ) ;
691
+ } ) ,
692
+ CheckAtom < Number > ( "0" )
693
+ ) ;
694
+ } ) ,
695
+ CheckAtom < Variable > ( "a" )
696
+ ) ;
697
+ } ) ,
698
+ CheckAtom < Variable > ( "b" )
699
+ ) ;
700
+ } ) ,
701
+ CheckAtom < Variable > ( "c" ) ) ;
702
+ Assert . Collection ( table . Cells [ 2 ] [ 0 ] , CheckAtom < Variable > ( "d" ) ) ;
703
+ } ) ( Assert . Single ( list ) ) ;
704
+ Assert . Equal ( @"1\\ 2\left( 3\begin{array}{ll}4&\left[ 5\\ 6\right] \\ \left\{ 7\left\{ \, \begin{array}{l}\textstyle 8\\ \textstyle 9\end{array}\right. 0\right\} a\end{array}b\right) c\\ d" , LaTeXParser . MathListToLaTeX ( list ) . ToString ( ) ) ;
705
+ }
706
+
476
707
[ Fact ]
477
708
public void TestTableWithColumns ( ) {
478
709
var list = ParseLaTeX ( @"x & y \\ z & w" ) ;
@@ -1017,7 +1248,7 @@ public void TestHelpfulErrorMessage(string input, int index, string expected) {
1017
1248
InlineData ( @"1+\left" , @"Error: Missing delimiter for left
1018
1249
1+\left
1019
1250
↑ (pos 7)" ) ,
1020
- InlineData ( @"\left{" , @"Error: Missing \right
1251
+ InlineData ( @"\left{" , @"Error: Missing \right for \left with delimiter {
1021
1252
\left{
1022
1253
↑ (pos 6)" ) ,
1023
1254
InlineData ( @"\left(\frac12\right" , @"Error: Missing delimiter for right
@@ -1038,10 +1269,10 @@ public void TestHelpfulErrorMessage(string input, int index, string expected) {
1038
1269
InlineData ( @"5 + 3 \right)" , @"Error: Missing \left
1039
1270
5 + 3 \right)
1040
1271
↑ (pos 12)" ) ,
1041
- InlineData ( @"\left(\frac12" , @"Error: Missing \right
1272
+ InlineData ( @"\left(\frac12" , @"Error: Missing \right for \left with delimiter (
1042
1273
\left(\frac12
1043
1274
↑ (pos 13)" ) ,
1044
- InlineData ( @"\left(5 + \left| \frac12 \right)" , @"Error: Missing \right
1275
+ InlineData ( @"\left(5 + \left| \frac12 \right)" , @"Error: Missing \right for \left with delimiter (
1045
1276
···left| \frac12 \right)
1046
1277
↑ (pos 32)" ) ,
1047
1278
InlineData ( @"5+ \left|\frac12\right| \right)" , @"Error: Missing \left
@@ -1059,7 +1290,10 @@ public void TestHelpfulErrorMessage(string input, int index, string expected) {
1059
1290
InlineData ( @"\begin{matrix parens}" , @"Error: Missing }
1060
1291
\begin{matrix parens}
1061
1292
↑ (pos 14)" ) , // no spaces in env
1062
- InlineData ( @"\begin{matrix} x" , @"Error: Missing \end
1293
+ InlineData ( @"\begin{matrix}" , @"Error: Missing \end for \begin{matrix}
1294
+ \begin{matrix}
1295
+ ↑ (pos 14)" ) ,
1296
+ InlineData ( @"\begin{matrix} x" , @"Error: Missing \end for \begin{matrix}
1063
1297
\begin{matrix} x
1064
1298
↑ (pos 16)" ) ,
1065
1299
InlineData ( @"\begin{matrix} x \end" , @"Error: Missing {
@@ -1107,6 +1341,9 @@ public void TestHelpfulErrorMessage(string input, int index, string expected) {
1107
1341
InlineData ( @"\color{red blue}{xyz}" , @"Error: Missing }
1108
1342
\color{red blue}{xyz}
1109
1343
↑ (pos 11)" ) ,
1344
+ InlineData ( @"\left(\begin{matrix}\right)" , @"Error: Missing \end{matrix}
1345
+ ···(\begin{matrix}\right)
1346
+ ↑ (pos 26)" ) ,
1110
1347
]
1111
1348
public void TestErrors ( string badInput , string expected ) {
1112
1349
var ( list , actual ) = LaTeXParser . MathListFromLaTeX ( badInput ) ;
0 commit comments