mathematical 1.2.2 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +24 -45
- data/Rakefile +6 -0
- data/ext/mathematical/extconf.rb +1 -1
- data/ext/mathematical/lasem/Makefile +1037 -0
- data/ext/mathematical/lasem/config.h +87 -0
- data/ext/mathematical/lasem/docs/Makefile +793 -0
- data/ext/mathematical/lasem/docs/reference/Makefile +735 -0
- data/ext/mathematical/lasem/docs/reference/lasem/Makefile +1023 -0
- data/ext/mathematical/lasem/itex2mml/Makefile +742 -0
- data/ext/mathematical/lasem/itex2mml/lex.yy.c +6294 -0
- data/ext/mathematical/lasem/itex2mml/y.tab.c +5796 -0
- data/ext/mathematical/lasem/itex2mml/y.tab.h +378 -0
- data/ext/mathematical/lasem/po/Makefile +413 -0
- data/ext/mathematical/lasem/src/Makefile +1322 -0
- data/ext/mathematical/lasem/src/lsmdomenumtypes.c +99 -0
- data/ext/mathematical/lasem/src/lsmdomenumtypes.h +26 -0
- data/ext/mathematical/lasem/src/lsmmathmlattributes.c +22 -0
- data/ext/mathematical/lasem/src/lsmmathmlenums.c +8 -0
- data/ext/mathematical/lasem/src/lsmmathmlenums.h +7 -0
- data/ext/mathematical/lasem/src/lsmmathmlenumtypes.c +737 -0
- data/ext/mathematical/lasem/src/lsmmathmlenumtypes.h +93 -0
- data/ext/mathematical/lasem/src/lsmmathmlmathelement.c +9 -1
- data/ext/mathematical/lasem/src/lsmmathmlstyle.h +8 -0
- data/ext/mathematical/lasem/src/lsmmathmlstyleelement.c +78 -0
- data/ext/mathematical/lasem/src/lsmmathmlstyleelement.h +7 -0
- data/ext/mathematical/lasem/src/lsmmathmltablerowelement.c +2 -2
- data/ext/mathematical/lasem/src/lsmmathmltraits.h +8 -0
- data/ext/mathematical/lasem/src/lsmsvgenumtypes.c +1083 -0
- data/ext/mathematical/lasem/src/lsmsvgenumtypes.h +111 -0
- data/ext/mathematical/lasem/tests/Makefile +765 -0
- data/ext/mathematical/mtex2MML/Makefile +25 -16
- data/ext/mathematical/mtex2MML/build/libmtex2MML.a +0 -0
- data/ext/mathematical/mtex2MML/build/mtex2MML.h +1 -1
- data/ext/mathematical/mtex2MML/src/lex.yy.c +3140 -3130
- data/ext/mathematical/mtex2MML/src/main.c +1 -1
- data/ext/mathematical/mtex2MML/src/mtex2MML.h +1 -1
- data/ext/mathematical/mtex2MML/src/mtex2MML.l +4 -1
- data/ext/mathematical/mtex2MML/src/mtex2MML.y +41 -42
- data/ext/mathematical/mtex2MML/src/parse_extras.c +148 -58
- data/ext/mathematical/mtex2MML/src/parse_extras.h +11 -3
- data/ext/mathematical/mtex2MML/src/y.tab.c +5902 -6075
- data/ext/mathematical/mtex2MML/src/y.tab.h +306 -313
- data/ext/mathematical/mtex2MML/tests/basic.c +2 -2
- data/ext/mathematical/mtex2MML/tests/deps/trim/trim.h +1 -1
- data/ext/mathematical/mtex2MML/tests/maliciousness.c +0 -1
- data/ext/mathematical/mtex2MML/tests/mathjax.c +11 -1
- data/ext/mathematical/mtex2MML/tests/numbered_equations.c +28 -1
- data/lib/mathematical/version.rb +1 -1
- data/mathematical.gemspec +3 -3
- data/test/mathematical/fixtures/png/numeric_test_1.png +0 -0
- data/test/mathematical/fixtures/png/numeric_test_3.png +0 -0
- data/test/mathematical/fixtures_test.rb +1 -6
- data/test/mathematical/mathjax_test.rb +2 -0
- data/test/test_helper.rb +10 -0
- metadata +28 -11
@@ -73,7 +73,7 @@ int display_style = 0;
|
|
73
73
|
"\\hline" |
|
74
74
|
"\\hdashline" { /* Ignore */ ;}
|
75
75
|
|
76
|
-
|
76
|
+
.?%.+$ { /* Ignore */ ;}
|
77
77
|
|
78
78
|
"{" {mtex2MML_rowposn = 2; if(mtex2MML_inoptarg[mtex2MML_optarg_ind] != 0) mtex2MML_inoptarg[mtex2MML_optarg_ind]++; return MROWOPEN;}
|
79
79
|
"}" {if(mtex2MML_inoptarg[mtex2MML_optarg_ind] != 0) mtex2MML_inoptarg[mtex2MML_optarg_ind]--; return MROWCLOSE;}
|
@@ -1126,6 +1126,9 @@ int display_style = 0;
|
|
1126
1126
|
"\\begin" {mtex2MML_env_start = 1; BEGIN(MATHENV); return BEGINENV;}
|
1127
1127
|
"\\end" {BEGIN(MATHENV); return ENDENV;}
|
1128
1128
|
|
1129
|
+
"\\notag" |
|
1130
|
+
"\\nonumber" { /* ignore, but address in .y */}
|
1131
|
+
|
1129
1132
|
"\\substack" {return SUBSTACK;}
|
1130
1133
|
|
1131
1134
|
"\\cases" {return CASES;}
|
@@ -281,7 +281,7 @@ struct css_colors *colors = NULL;
|
|
281
281
|
char * n = (char *) malloc(256);
|
282
282
|
snprintf(n, 256, "%d", global_label);
|
283
283
|
global_label++;
|
284
|
-
char *prefix = mtex2MML_copy3("
|
284
|
+
char *prefix = mtex2MML_copy3("<mtd><mtext>(", n, ")</mtext></mtd>");
|
285
285
|
mtex2MML_free_string(n);
|
286
286
|
|
287
287
|
return prefix;
|
@@ -1592,7 +1592,11 @@ mbox: MBOX closedTerm {
|
|
1592
1592
|
};
|
1593
1593
|
|
1594
1594
|
bold: BOLD closedTerm {
|
1595
|
-
|
1595
|
+
/* TODO: stupid hack to get bold mover working */
|
1596
|
+
char * b = str_replace($2, "<mi>", "<mi mathvariant=\"bold\">");
|
1597
|
+
|
1598
|
+
$$ = mtex2MML_copy3("<mstyle mathvariant=\"bold\">", b, "</mstyle>");
|
1599
|
+
mtex2MML_free_string(b);
|
1596
1600
|
mtex2MML_free_string($2);
|
1597
1601
|
};
|
1598
1602
|
|
@@ -2602,15 +2606,13 @@ emptymrow: EMPTYMROW {
|
|
2602
2606
|
$$ = mtex2MML_copy_string("<mrow/>");
|
2603
2607
|
};
|
2604
2608
|
|
2605
|
-
mathenv: BEGINENV EQUATION
|
2606
|
-
|
2607
|
-
$$ = mtex2MML_copy3("<mtable><mlabeledtr><mtd>", $3, n);
|
2609
|
+
mathenv: BEGINENV EQUATION tableRowList ENDENV EQUATION {
|
2610
|
+
$$ = mtex2MML_copy3("<mtable>", $3, "</mtable>");
|
2608
2611
|
|
2609
2612
|
mtex2MML_free_string($3);
|
2610
|
-
mtex2MML_free_string(n);
|
2611
2613
|
}
|
2612
|
-
| BEGINENV EQUATION_STAR
|
2613
|
-
$$ = mtex2MML_copy3("<mtable
|
2614
|
+
| BEGINENV EQUATION_STAR tableRowList ENDENV EQUATION_STAR {
|
2615
|
+
$$ = mtex2MML_copy3("<mtable>", $3, "</mtable>");
|
2614
2616
|
|
2615
2617
|
mtex2MML_free_string($3);
|
2616
2618
|
}
|
@@ -2669,21 +2671,17 @@ mathenv: BEGINENV EQUATION compoundTermList ENDENV EQUATION {
|
|
2669
2671
|
char *row_data = combine_row_data(&environment_data_stack);
|
2670
2672
|
|
2671
2673
|
char * s1 = mtex2MML_copy3("<mrow><mtable displaystyle=\"true\" columnalign=\"right center left\" columnspacing=\"thickmathspace\" ", row_data, ">");
|
2672
|
-
char * s2 = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2673
|
-
char * n = mtex2MML_global_label();
|
2674
2674
|
|
2675
2675
|
if (encase == TOPENCLOSE) {
|
2676
|
-
char *t = mtex2MML_copy3("
|
2676
|
+
char *t = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2677
2677
|
$$ = mtex2MML_copy3("<menclose notation=\"top\">", t, "</menclose>");
|
2678
2678
|
mtex2MML_free_string(t);
|
2679
2679
|
}
|
2680
2680
|
else
|
2681
|
-
$$ = mtex2MML_copy3("
|
2681
|
+
$$ = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2682
2682
|
|
2683
2683
|
mtex2MML_free_string($3);
|
2684
|
-
mtex2MML_free_string(n);
|
2685
2684
|
mtex2MML_free_string(s1);
|
2686
|
-
mtex2MML_free_string(s2);
|
2687
2685
|
mtex2MML_free_string(row_data);
|
2688
2686
|
}
|
2689
2687
|
| BEGINENV EQNARRAY_STAR tableRowList ENDENV EQNARRAY_STAR {
|
@@ -2706,21 +2704,17 @@ mathenv: BEGINENV EQUATION compoundTermList ENDENV EQUATION {
|
|
2706
2704
|
char *row_data = combine_row_data(&environment_data_stack);
|
2707
2705
|
|
2708
2706
|
char * s1 = mtex2MML_copy3("<mrow><mtable displaystyle=\"true\" ", row_data, ">");
|
2709
|
-
char * s2 = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2710
|
-
char * n = mtex2MML_global_label();
|
2711
2707
|
|
2712
2708
|
if (encase == TOPENCLOSE) {
|
2713
|
-
char *t = mtex2MML_copy3("
|
2709
|
+
char *t = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2714
2710
|
$$ = mtex2MML_copy3("<menclose notation=\"top\">", t, "</menclose>");
|
2715
2711
|
mtex2MML_free_string(t);
|
2716
2712
|
}
|
2717
2713
|
else
|
2718
|
-
$$ = mtex2MML_copy3("
|
2714
|
+
$$ = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2719
2715
|
|
2720
2716
|
mtex2MML_free_string($3);
|
2721
|
-
mtex2MML_free_string(n);
|
2722
2717
|
mtex2MML_free_string(s1);
|
2723
|
-
mtex2MML_free_string(s2);
|
2724
2718
|
mtex2MML_free_string(row_data);
|
2725
2719
|
}
|
2726
2720
|
| BEGINENV GATHER_STAR tableRowList ENDENV GATHER_STAR {
|
@@ -2743,21 +2737,17 @@ mathenv: BEGINENV EQUATION compoundTermList ENDENV EQUATION {
|
|
2743
2737
|
char *row_data = combine_row_data(&environment_data_stack);
|
2744
2738
|
|
2745
2739
|
char * s1 = mtex2MML_copy3("<mrow><mtable displaystyle=\"true\" ", row_data, ">");
|
2746
|
-
char * s2 = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2747
|
-
char * n = mtex2MML_global_label();
|
2748
2740
|
|
2749
2741
|
if (encase == TOPENCLOSE) {
|
2750
|
-
char *t = mtex2MML_copy3("
|
2742
|
+
char *t = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2751
2743
|
$$ = mtex2MML_copy3("<menclose notation=\"top\">", t, "</menclose>");
|
2752
2744
|
mtex2MML_free_string(t);
|
2753
2745
|
}
|
2754
2746
|
else
|
2755
|
-
$$ = mtex2MML_copy3("
|
2747
|
+
$$ = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2756
2748
|
|
2757
2749
|
mtex2MML_free_string($3);
|
2758
|
-
mtex2MML_free_string(n);
|
2759
2750
|
mtex2MML_free_string(s1);
|
2760
|
-
mtex2MML_free_string(s2);
|
2761
2751
|
mtex2MML_free_string(row_data);
|
2762
2752
|
}
|
2763
2753
|
| BEGINENV MULTLINE_STAR tableRowList ENDENV MULTLINE_STAR {
|
@@ -2935,21 +2925,17 @@ mathenv: BEGINENV EQUATION compoundTermList ENDENV EQUATION {
|
|
2935
2925
|
char *row_data = combine_row_data(&environment_data_stack);
|
2936
2926
|
|
2937
2927
|
char * s1 = mtex2MML_copy3("<mrow><mtable displaystyle=\"true\" columnspacing=\"0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em\" columnalign=\"right left right left right left right left right left\" ", row_data, ">");
|
2938
|
-
char * s2 = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2939
|
-
char * n = mtex2MML_global_label();
|
2940
2928
|
|
2941
2929
|
if (encase == TOPENCLOSE) {
|
2942
|
-
char *t = mtex2MML_copy3("
|
2930
|
+
char *t = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2943
2931
|
$$ = mtex2MML_copy3("<menclose notation=\"top\">", t, "</menclose>");
|
2944
2932
|
mtex2MML_free_string(t);
|
2945
2933
|
}
|
2946
2934
|
else
|
2947
|
-
$$ = mtex2MML_copy3("
|
2935
|
+
$$ = mtex2MML_copy3(s1, $3, "</mtable></mrow>");
|
2948
2936
|
|
2949
2937
|
mtex2MML_free_string($3);
|
2950
|
-
mtex2MML_free_string(n);
|
2951
2938
|
mtex2MML_free_string(s1);
|
2952
|
-
mtex2MML_free_string(s2);
|
2953
2939
|
mtex2MML_free_string(row_data);
|
2954
2940
|
}
|
2955
2941
|
| BEGINENV ALIGNENV_STAR tableRowList ENDENV ALIGNENV_STAR {
|
@@ -2973,22 +2959,18 @@ mathenv: BEGINENV EQUATION compoundTermList ENDENV EQUATION {
|
|
2973
2959
|
char *row_data = combine_row_data(&environment_data_stack);
|
2974
2960
|
|
2975
2961
|
char * s1 = mtex2MML_copy3("<mrow><mtable displaystyle=\"true\" columnalign=\"right left right left right left right left right left\" columnspacing=\"0em\" ", row_data, ">");
|
2976
|
-
char * s2 = mtex2MML_copy3(s1, $5, "</mtable></mrow>");
|
2977
|
-
char * n = mtex2MML_global_label();
|
2978
2962
|
|
2979
2963
|
if (encase == TOPENCLOSE) {
|
2980
|
-
char *t = mtex2MML_copy3("
|
2964
|
+
char *t = mtex2MML_copy3(s1, $5, "</mtable></mrow>");
|
2981
2965
|
$$ = mtex2MML_copy3("<menclose notation=\"top\">", t, "</menclose>");
|
2982
2966
|
mtex2MML_free_string(t);
|
2983
2967
|
}
|
2984
2968
|
else
|
2985
|
-
$$ = mtex2MML_copy3("
|
2969
|
+
$$ = mtex2MML_copy3(s1, $5, "</mtable></mrow>");
|
2986
2970
|
|
2987
2971
|
mtex2MML_free_string($3);
|
2988
2972
|
mtex2MML_free_string($5);
|
2989
|
-
mtex2MML_free_string(n);
|
2990
2973
|
mtex2MML_free_string(s1);
|
2991
|
-
mtex2MML_free_string(s2);
|
2992
2974
|
mtex2MML_free_string(row_data);
|
2993
2975
|
}
|
2994
2976
|
| BEGINENV ALIGNAT_STAR ALIGNATVALUE END tableRowList ENDENV ALIGNAT_STAR {
|
@@ -3288,7 +3270,21 @@ tableRowList: tableRow {
|
|
3288
3270
|
};
|
3289
3271
|
|
3290
3272
|
tableRow: simpleTableRow {
|
3291
|
-
|
3273
|
+
int has_eqn_number = fetch_eqn_number(&environment_data_stack);
|
3274
|
+
|
3275
|
+
if (has_eqn_number && strcmp($1, "<mtd/>") != 0) {
|
3276
|
+
char * n = mtex2MML_global_label();
|
3277
|
+
|
3278
|
+
char *s1 = mtex2MML_copy3("<mlabeledtr>", n, $1);
|
3279
|
+
$$ = mtex2MML_copy2(s1, "</mlabeledtr>");
|
3280
|
+
|
3281
|
+
mtex2MML_free_string(n);
|
3282
|
+
mtex2MML_free_string(s1);
|
3283
|
+
}
|
3284
|
+
else {
|
3285
|
+
$$ = mtex2MML_copy3("<mtr>", $1, "</mtr>");
|
3286
|
+
}
|
3287
|
+
|
3292
3288
|
mtex2MML_free_string($1);
|
3293
3289
|
}
|
3294
3290
|
| optsTableRow {
|
@@ -3337,7 +3333,7 @@ tableCell: {
|
|
3337
3333
|
$$ = mtex2MML_copy_string("<mtd/>");
|
3338
3334
|
}
|
3339
3335
|
| compoundTermList {
|
3340
|
-
if (current_env_type(&environment_data_stack) != ENV_MULTLINE) {
|
3336
|
+
if (current_env_type(&environment_data_stack) != ENV_MULTLINE && current_env_type(&environment_data_stack) != ENV_MULTLINESTAR) {
|
3341
3337
|
$$ = mtex2MML_copy3("<mtd>", $1, "</mtd>");
|
3342
3338
|
}
|
3343
3339
|
else {
|
@@ -3404,13 +3400,15 @@ colspan: COLSPAN ATTRLIST {
|
|
3404
3400
|
|
3405
3401
|
%%
|
3406
3402
|
|
3407
|
-
// see
|
3403
|
+
// see http://git.io/vk8Sz
|
3408
3404
|
void envdata_copy(void *_dst, const void *_src)
|
3409
3405
|
{
|
3410
3406
|
envdata_t *dst = (envdata_t*)_dst, *src = (envdata_t*)_src;
|
3411
3407
|
dst->rowspacing = src->rowspacing ? strdup(src->rowspacing) : NULL;
|
3412
3408
|
dst->rowlines = src->rowlines ? strdup(src->rowlines) : NULL;
|
3413
|
-
dst->
|
3409
|
+
dst->environment_type = src->environment_type;
|
3410
|
+
utarray_new(dst->eqn_numbers, &ut_int_icd);
|
3411
|
+
utarray_concat(dst->eqn_numbers, src->eqn_numbers);
|
3414
3412
|
dst->line_count = src->line_count;
|
3415
3413
|
}
|
3416
3414
|
|
@@ -3419,6 +3417,7 @@ void envdata_dtor(void *_elt)
|
|
3419
3417
|
envdata_t *elt = (envdata_t*)_elt;
|
3420
3418
|
if (elt->rowspacing) { free(elt->rowspacing); }
|
3421
3419
|
if (elt->rowlines) { free(elt->rowlines); }
|
3420
|
+
if (elt->eqn_numbers) { utarray_free(elt->eqn_numbers); }
|
3422
3421
|
}
|
3423
3422
|
|
3424
3423
|
UT_icd envdata_icd = {sizeof(envdata_t), NULL, envdata_copy, envdata_dtor};
|
@@ -1,50 +1,85 @@
|
|
1
1
|
#include <stdio.h>
|
2
2
|
#include <stdlib.h>
|
3
3
|
#include <string.h>
|
4
|
+
#include <math.h>
|
4
5
|
|
5
6
|
#include "parse_extras.h"
|
6
7
|
#include "string_extras.h"
|
7
8
|
|
8
|
-
|
9
|
+
static const char *BEGIN = "\\begin";
|
10
|
+
static const char *END = "\\end";
|
11
|
+
static const char *BEGIN_SVG = "begin{svg}";
|
12
|
+
|
13
|
+
const char *HLINE = "\\hline", *HDASHLINE = "\\hdashline",
|
14
|
+
*LINE_SEPARATOR = "\\\\",
|
15
|
+
*CR_SEPARATOR = "\\cr",
|
16
|
+
*NEWLINE_SEPARATOR = "\\newline",
|
17
|
+
*EM_PATTERN_BEGIN = "\\[", *EM_PATTERN_END = "]",
|
18
|
+
*NOTAG = "\\notag", *NONUMBER = "\\nonumber";
|
19
|
+
|
20
|
+
int determine_environment(const char *environment)
|
9
21
|
{
|
10
|
-
|
11
|
-
|
22
|
+
if (strstr(environment, "\\end{smallmatrix}") != NULL) {
|
23
|
+
return ENV_SMALLMATRIX;
|
24
|
+
} else if (strstr(environment, "\\end{gather}") != NULL) {
|
25
|
+
return ENV_GATHER;
|
26
|
+
} else if (strstr(environment, "\\end{gathered}") != NULL) {
|
27
|
+
return ENV_GATHERED;
|
28
|
+
} else if (strstr(environment, "\\end{eqnarray") != NULL) {
|
29
|
+
return ENV_EQNARRAY;
|
30
|
+
} else if (strstr(environment, "\\end{multline}") != NULL) {
|
31
|
+
return ENV_MULTLINE;
|
32
|
+
} else if (strstr(environment, "\\end{multline*}") != NULL) {
|
33
|
+
return ENV_MULTLINESTAR;
|
34
|
+
} else if (strstr(environment, "\\end{alignat") != NULL) {
|
35
|
+
return ENV_ALIGNAT;
|
36
|
+
} else if (strstr(environment, "\\end{aligned}") != NULL) {
|
37
|
+
return ENV_ALIGNED;
|
38
|
+
} else if (strstr(environment, "\\end{equation}") != NULL) {
|
39
|
+
return ENV_EQUATION;
|
40
|
+
} else if (strstr(environment, "\\end{align}") != NULL) {
|
41
|
+
return ENV_ALIGN;
|
42
|
+
}
|
12
43
|
|
44
|
+
return OTHER;
|
45
|
+
}
|
46
|
+
|
47
|
+
int identify_eqn_number(envType environment_type, char *line)
|
48
|
+
{
|
49
|
+
// some environments have labelling for every row.
|
50
|
+
// supress it if it has a \notag or \nonumber
|
51
|
+
if (environment_type == ENV_EQUATION || \
|
52
|
+
environment_type == ENV_ALIGN || \
|
53
|
+
environment_type == ENV_ALIGNAT ||
|
54
|
+
environment_type == ENV_EQNARRAY) {
|
55
|
+
if (line == NULL)
|
56
|
+
return 1;
|
57
|
+
else
|
58
|
+
return !(strstr(line, NOTAG) != NULL || \
|
59
|
+
strstr(line, NONUMBER) != NULL);
|
60
|
+
}
|
61
|
+
else {
|
62
|
+
return 0;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
void env_replacements(UT_array **environment_data_stack, encaseType * encase, const char *environment)
|
67
|
+
{
|
13
68
|
// if not an environment, don't bother going on
|
14
|
-
if ((strstr(environment,
|
69
|
+
if ((strstr(environment, BEGIN) == NULL && strstr(environment, END) == NULL) || strstr(environment, BEGIN_SVG)) {
|
15
70
|
return;
|
16
71
|
}
|
17
72
|
|
18
73
|
UT_array *array_stack;
|
19
74
|
UT_array *row_spacing_stack;
|
20
75
|
UT_array *rowlines_stack;
|
76
|
+
UT_array *eqn_number_stack;
|
21
77
|
|
22
78
|
char *tok = NULL, *at_top = NULL,
|
23
|
-
*temp = "", **
|
79
|
+
*temp = "", **prev_stack_item,
|
24
80
|
*a, *em_str;
|
25
81
|
|
26
|
-
|
27
|
-
if (strstr(environment, "\\end{smallmatrix}") != NULL) {
|
28
|
-
environmentType = ENV_SMALLMATRIX;
|
29
|
-
} else if (strstr(environment, "\\end{gathered}") != NULL) {
|
30
|
-
environmentType = ENV_GATHERED;
|
31
|
-
} else if (strstr(environment, "\\end{eqnarray") != NULL) {
|
32
|
-
environmentType = ENV_EQNARRAY;
|
33
|
-
} else if (strstr(environment, "\\end{multline") != NULL) {
|
34
|
-
environmentType = ENV_MULTLINE;
|
35
|
-
} else if (strstr(environment, "\\end{alignat") != NULL) {
|
36
|
-
environmentType = ENV_ALIGNAT;
|
37
|
-
} else if (strstr(environment, "\\end{aligned}") != NULL) {
|
38
|
-
environmentType = ENV_ALIGNED;
|
39
|
-
}
|
40
|
-
|
41
|
-
const char *hline = "\\hline", *hdashline = "\\hdashline",
|
42
|
-
*line_separator = "\\\\",
|
43
|
-
*cr_separator = "\\cr",
|
44
|
-
*newline_separator = "\\newline",
|
45
|
-
*em_pattern_begin = "\\[", *em_pattern_end = "]";
|
46
|
-
|
47
|
-
int rowlines_stack_len = 0, em_offset = 0;
|
82
|
+
int rowlines_stack_len = 0, em_offset = 0, eqn = 0, i = 0, insertion_idx = 0;
|
48
83
|
|
49
84
|
char *dupe_environment = strdup(environment);
|
50
85
|
char *line = strtok(dupe_environment, "\n");
|
@@ -53,36 +88,55 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
|
|
53
88
|
utarray_new(array_stack, &ut_str_icd);
|
54
89
|
utarray_new(row_spacing_stack, &ut_str_icd);
|
55
90
|
utarray_new(rowlines_stack, &ut_str_icd);
|
91
|
+
utarray_new(eqn_number_stack, &ut_int_icd);
|
56
92
|
|
57
93
|
while (line != NULL) {
|
58
94
|
utarray_push_back(array_stack, &line);
|
59
95
|
|
60
|
-
if (strstr(line,
|
96
|
+
if (strstr(line, END) != NULL) {
|
97
|
+
envType environment_type = determine_environment(line);
|
98
|
+
|
61
99
|
while (utarray_len(array_stack) > 0) {
|
62
|
-
|
100
|
+
prev_stack_item = (char **)utarray_back(array_stack);
|
63
101
|
|
64
102
|
rowlines_stack_len = utarray_len(rowlines_stack);
|
65
|
-
at_top = strstr(*
|
103
|
+
at_top = strstr(*prev_stack_item, BEGIN);
|
66
104
|
|
67
105
|
// we've reached the top, but there looks like there might be some data
|
68
|
-
if (at_top != NULL && strstr(*
|
69
|
-
strstr(*
|
70
|
-
strstr(*
|
71
|
-
if (strstr(*
|
106
|
+
if (at_top != NULL && strstr(*prev_stack_item, LINE_SEPARATOR) == NULL && \
|
107
|
+
strstr(*prev_stack_item, CR_SEPARATOR) == NULL && \
|
108
|
+
strstr(*prev_stack_item, NEWLINE_SEPARATOR) == NULL) {
|
109
|
+
if (strstr(*prev_stack_item, HLINE) != NULL || strstr(*prev_stack_item, HDASHLINE) != NULL) {
|
72
110
|
*encase = TOPENCLOSE;
|
73
111
|
}
|
74
|
-
|
112
|
+
// TODO: not super confident this is bulletproof
|
113
|
+
if (rowlines_stack_len == 0) {
|
114
|
+
eqn = identify_eqn_number(environment_type, *prev_stack_item);
|
115
|
+
utarray_push_back(eqn_number_stack, &eqn);
|
116
|
+
}
|
75
117
|
break;
|
76
118
|
}
|
77
119
|
|
120
|
+
// these environments are a bit...special. they still use
|
121
|
+
// the same line separators, so they tend to mess with "proper"
|
122
|
+
// labelled environments, because they exist within \begin{equation}
|
123
|
+
// if we find one, erase all the stored row info.
|
124
|
+
if (strstr(*prev_stack_item, "\\eqalign") != NULL || \
|
125
|
+
strstr(*prev_stack_item, "\\split") != NULL) {
|
126
|
+
for (i = rowlines_stack_len; i > 1; i--) {
|
127
|
+
utarray_pop_back(rowlines_stack);
|
128
|
+
utarray_pop_back(eqn_number_stack);
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
78
132
|
// looking for a hline/hdashline match
|
79
|
-
if (strstr(*
|
133
|
+
if (strstr(*prev_stack_item, HLINE) != NULL) {
|
80
134
|
if (rowlines_stack_len > 0) {
|
81
135
|
utarray_pop_back(rowlines_stack);
|
82
136
|
}
|
83
137
|
a = "solid";
|
84
138
|
utarray_push_back(rowlines_stack, &a);
|
85
|
-
} else if (strstr(*
|
139
|
+
} else if (strstr(*prev_stack_item, HDASHLINE) != NULL) {
|
86
140
|
if (rowlines_stack_len > 0) {
|
87
141
|
utarray_pop_back(rowlines_stack);
|
88
142
|
}
|
@@ -93,29 +147,32 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
|
|
93
147
|
utarray_push_back(rowlines_stack, &a);
|
94
148
|
}
|
95
149
|
|
150
|
+
eqn = identify_eqn_number(environment_type, *prev_stack_item);
|
151
|
+
utarray_push_back(eqn_number_stack, &eqn);
|
152
|
+
|
96
153
|
// if there's a line break...
|
97
|
-
if (strstr(*
|
98
|
-
strstr(*
|
99
|
-
strstr(*
|
100
|
-
//
|
101
|
-
if ( (tok = strstr(*
|
154
|
+
if (strstr(*prev_stack_item, LINE_SEPARATOR) != NULL || \
|
155
|
+
strstr(*prev_stack_item, CR_SEPARATOR) != NULL || \
|
156
|
+
strstr(*prev_stack_item, NEWLINE_SEPARATOR) != NULL) {
|
157
|
+
// ...with an emphasis match, add it...
|
158
|
+
if ( (tok = strstr(*prev_stack_item, EM_PATTERN_BEGIN)) != NULL) {
|
102
159
|
temp = tok + 2; // skip the first part ("\[")
|
103
|
-
if ( (tok = strstr(temp,
|
160
|
+
if ( (tok = strstr(temp, EM_PATTERN_END)) != NULL) {
|
104
161
|
em_offset = (int)(tok - temp);
|
105
162
|
char *s = strndup(temp, em_offset);
|
106
163
|
utarray_push_back(row_spacing_stack, &s);
|
107
164
|
free(s);
|
108
165
|
}
|
109
166
|
}
|
110
|
-
// otherwise, use the default
|
167
|
+
// ...otherwise, use the default emphasis
|
111
168
|
else {
|
112
|
-
if (
|
169
|
+
if (environment_type == ENV_SMALLMATRIX) {
|
113
170
|
em_str = "0.2em";
|
114
|
-
} else if (
|
171
|
+
} else if (environment_type == ENV_GATHERED) {
|
115
172
|
em_str = "1.0ex";
|
116
|
-
} else if (
|
173
|
+
} else if (environment_type == ENV_EQNARRAY || environment_type == ENV_ALIGNAT || environment_type == ENV_ALIGNED) {
|
117
174
|
em_str = "3pt";
|
118
|
-
} else if (
|
175
|
+
} else if (environment_type == ENV_MULTLINE || environment_type == ENV_MULTLINESTAR) {
|
119
176
|
em_str = "0.5em";
|
120
177
|
} else {
|
121
178
|
em_str = "0.5ex";
|
@@ -133,12 +190,20 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
|
|
133
190
|
}
|
134
191
|
}
|
135
192
|
|
136
|
-
|
137
|
-
|
193
|
+
// some environments only have one label for the whole environment,
|
194
|
+
// rather than a label per row. in that case, jam a label
|
195
|
+
// in the middle.
|
196
|
+
if (environment_type == ENV_GATHER || environment_type == ENV_MULTLINE) {
|
197
|
+
insertion_idx = ceil(utarray_len(eqn_number_stack) / 2);
|
198
|
+
eqn = 1;
|
199
|
+
utarray_insert(eqn_number_stack, &eqn, insertion_idx);
|
200
|
+
utarray_pop_back(eqn_number_stack);
|
138
201
|
}
|
202
|
+
perform_replacement(environment_data_stack, rowlines_stack, environment_type, eqn_number_stack, row_spacing_stack);
|
139
203
|
|
140
204
|
utarray_clear(row_spacing_stack);
|
141
205
|
utarray_clear(rowlines_stack);
|
206
|
+
utarray_clear(eqn_number_stack);
|
142
207
|
rowlines_stack_len = 0;
|
143
208
|
}
|
144
209
|
|
@@ -148,16 +213,22 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
|
|
148
213
|
utarray_free(array_stack);
|
149
214
|
utarray_free(row_spacing_stack);
|
150
215
|
utarray_free(rowlines_stack);
|
216
|
+
utarray_free(eqn_number_stack);
|
217
|
+
|
151
218
|
free(dupe_environment);
|
152
219
|
}
|
153
220
|
|
154
|
-
void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_stack, envType
|
221
|
+
void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_stack, envType environment_type, UT_array *eqn_number_stack, UT_array *row_spacing_stack)
|
155
222
|
{
|
156
223
|
char *a, *attr_rowlines, *attr_rowspacing;
|
157
224
|
envdata_t env_data;
|
158
225
|
|
159
226
|
// we cut the last char because we can always skip the first row
|
160
|
-
|
227
|
+
if (utarray_len(rowlines_stack) != 0)
|
228
|
+
utarray_pop_back(rowlines_stack);
|
229
|
+
|
230
|
+
if (utarray_len(eqn_number_stack) > 1)
|
231
|
+
utarray_erase(eqn_number_stack, 0, 1);
|
161
232
|
|
162
233
|
int line_count = utarray_len(rowlines_stack);
|
163
234
|
|
@@ -187,9 +258,9 @@ void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_s
|
|
187
258
|
utstring_new(s);
|
188
259
|
char **p=NULL;
|
189
260
|
while ( (p=(char**)utarray_prev(row_spacing_stack,p))) {
|
190
|
-
if (
|
261
|
+
if (environment_type == ENV_SMALLMATRIX && strcmp(*p, "0.5ex") == 0) {
|
191
262
|
utstring_printf(s, "%s ", "0.2em");
|
192
|
-
} else if (
|
263
|
+
} else if (environment_type == ENV_GATHERED && strcmp(*p, "0.5ex") == 0) {
|
193
264
|
utstring_printf(s, "%s ", "1.0ex");
|
194
265
|
} else {
|
195
266
|
utstring_printf(s, "%s ", *p);
|
@@ -200,9 +271,9 @@ void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_s
|
|
200
271
|
if (strlen(attr_rowspacing) > 0) {
|
201
272
|
remove_last_char(attr_rowspacing); // remove the final space
|
202
273
|
} else {
|
203
|
-
if (
|
274
|
+
if (environment_type == ENV_SMALLMATRIX) {
|
204
275
|
attr_rowspacing = "0.2em";
|
205
|
-
} else if (
|
276
|
+
} else if (environment_type == ENV_GATHERED) {
|
206
277
|
attr_rowspacing = "1.0ex";
|
207
278
|
} else {
|
208
279
|
attr_rowspacing = "0.5ex";
|
@@ -212,7 +283,8 @@ void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_s
|
|
212
283
|
// store pertinent metadata
|
213
284
|
env_data.rowspacing = attr_rowspacing;
|
214
285
|
env_data.rowlines = attr_rowlines;
|
215
|
-
env_data.
|
286
|
+
env_data.environment_type = environment_type;
|
287
|
+
env_data.eqn_numbers = eqn_number_stack;
|
216
288
|
env_data.line_count = line_count;
|
217
289
|
|
218
290
|
utarray_push_back(*environment_data_stack, &env_data);
|
@@ -339,6 +411,24 @@ const char *combine_row_data(UT_array **environment_data_stack)
|
|
339
411
|
return row_attr;
|
340
412
|
}
|
341
413
|
|
414
|
+
int fetch_eqn_number(UT_array **environment_data_stack)
|
415
|
+
{
|
416
|
+
// if no information was provided, expect nothing
|
417
|
+
if (utarray_len(*environment_data_stack) == 0) {
|
418
|
+
return 0;
|
419
|
+
}
|
420
|
+
|
421
|
+
envdata_t *row_data_elem = (envdata_t*) utarray_front(*environment_data_stack);
|
422
|
+
if (utarray_len(row_data_elem->eqn_numbers) == 0) {
|
423
|
+
return 0;
|
424
|
+
}
|
425
|
+
|
426
|
+
int *e = (int*) utarray_back(row_data_elem->eqn_numbers);
|
427
|
+
utarray_pop_back(row_data_elem->eqn_numbers);
|
428
|
+
|
429
|
+
return *e;
|
430
|
+
}
|
431
|
+
|
342
432
|
float extract_number_from_pxstring(const char * str)
|
343
433
|
{
|
344
434
|
float dbl;
|
@@ -434,7 +524,7 @@ envType current_env_type(UT_array **environment_data_stack)
|
|
434
524
|
|
435
525
|
envdata_t *row_data_elem = (envdata_t*) utarray_front(*environment_data_stack);
|
436
526
|
|
437
|
-
return row_data_elem->
|
527
|
+
return row_data_elem->environment_type;
|
438
528
|
}
|
439
529
|
|
440
530
|
int current_env_line_count(UT_array **environment_data_stack)
|