mathematical 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -45
  3. data/Rakefile +6 -0
  4. data/ext/mathematical/extconf.rb +1 -1
  5. data/ext/mathematical/lasem/Makefile +1037 -0
  6. data/ext/mathematical/lasem/config.h +87 -0
  7. data/ext/mathematical/lasem/docs/Makefile +793 -0
  8. data/ext/mathematical/lasem/docs/reference/Makefile +735 -0
  9. data/ext/mathematical/lasem/docs/reference/lasem/Makefile +1023 -0
  10. data/ext/mathematical/lasem/itex2mml/Makefile +742 -0
  11. data/ext/mathematical/lasem/itex2mml/lex.yy.c +6294 -0
  12. data/ext/mathematical/lasem/itex2mml/y.tab.c +5796 -0
  13. data/ext/mathematical/lasem/itex2mml/y.tab.h +378 -0
  14. data/ext/mathematical/lasem/po/Makefile +413 -0
  15. data/ext/mathematical/lasem/src/Makefile +1322 -0
  16. data/ext/mathematical/lasem/src/lsmdomenumtypes.c +99 -0
  17. data/ext/mathematical/lasem/src/lsmdomenumtypes.h +26 -0
  18. data/ext/mathematical/lasem/src/lsmmathmlattributes.c +22 -0
  19. data/ext/mathematical/lasem/src/lsmmathmlenums.c +8 -0
  20. data/ext/mathematical/lasem/src/lsmmathmlenums.h +7 -0
  21. data/ext/mathematical/lasem/src/lsmmathmlenumtypes.c +737 -0
  22. data/ext/mathematical/lasem/src/lsmmathmlenumtypes.h +93 -0
  23. data/ext/mathematical/lasem/src/lsmmathmlmathelement.c +9 -1
  24. data/ext/mathematical/lasem/src/lsmmathmlstyle.h +8 -0
  25. data/ext/mathematical/lasem/src/lsmmathmlstyleelement.c +78 -0
  26. data/ext/mathematical/lasem/src/lsmmathmlstyleelement.h +7 -0
  27. data/ext/mathematical/lasem/src/lsmmathmltablerowelement.c +2 -2
  28. data/ext/mathematical/lasem/src/lsmmathmltraits.h +8 -0
  29. data/ext/mathematical/lasem/src/lsmsvgenumtypes.c +1083 -0
  30. data/ext/mathematical/lasem/src/lsmsvgenumtypes.h +111 -0
  31. data/ext/mathematical/lasem/tests/Makefile +765 -0
  32. data/ext/mathematical/mtex2MML/Makefile +25 -16
  33. data/ext/mathematical/mtex2MML/build/libmtex2MML.a +0 -0
  34. data/ext/mathematical/mtex2MML/build/mtex2MML.h +1 -1
  35. data/ext/mathematical/mtex2MML/src/lex.yy.c +3140 -3130
  36. data/ext/mathematical/mtex2MML/src/main.c +1 -1
  37. data/ext/mathematical/mtex2MML/src/mtex2MML.h +1 -1
  38. data/ext/mathematical/mtex2MML/src/mtex2MML.l +4 -1
  39. data/ext/mathematical/mtex2MML/src/mtex2MML.y +41 -42
  40. data/ext/mathematical/mtex2MML/src/parse_extras.c +148 -58
  41. data/ext/mathematical/mtex2MML/src/parse_extras.h +11 -3
  42. data/ext/mathematical/mtex2MML/src/y.tab.c +5902 -6075
  43. data/ext/mathematical/mtex2MML/src/y.tab.h +306 -313
  44. data/ext/mathematical/mtex2MML/tests/basic.c +2 -2
  45. data/ext/mathematical/mtex2MML/tests/deps/trim/trim.h +1 -1
  46. data/ext/mathematical/mtex2MML/tests/maliciousness.c +0 -1
  47. data/ext/mathematical/mtex2MML/tests/mathjax.c +11 -1
  48. data/ext/mathematical/mtex2MML/tests/numbered_equations.c +28 -1
  49. data/lib/mathematical/version.rb +1 -1
  50. data/mathematical.gemspec +3 -3
  51. data/test/mathematical/fixtures/png/numeric_test_1.png +0 -0
  52. data/test/mathematical/fixtures/png/numeric_test_3.png +0 -0
  53. data/test/mathematical/fixtures_test.rb +1 -6
  54. data/test/mathematical/mathjax_test.rb +2 -0
  55. data/test/test_helper.rb +10 -0
  56. metadata +28 -11
@@ -14,7 +14,7 @@ int main (int argc, char ** argv)
14
14
  int bForbidMarkup = 0;
15
15
  int arg = 1;
16
16
 
17
- for (arg; arg < argc; arg++) {
17
+ for (; arg < argc; arg++) {
18
18
  char* args = argv[arg];
19
19
 
20
20
  if (strcmp(args, "--version") == 0 || strcmp(args, "-v") == 0) {
@@ -1,7 +1,7 @@
1
1
  #ifndef MTEX2MML_H
2
2
  #define MTEX2MML_H
3
3
 
4
- #define MTEX2MML_VERSION "1.0.1"
4
+ #define MTEX2MML_VERSION "1.1.1"
5
5
 
6
6
  #ifdef __cplusplus
7
7
  extern "C" {
@@ -73,7 +73,7 @@ int display_style = 0;
73
73
  "\\hline" |
74
74
  "\\hdashline" { /* Ignore */ ;}
75
75
 
76
- ^%.+ { /* Ignore */ ;}
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("</mtd><mtd><mtext>(", n, ")</mtext></mtd></mlabeledtr></mtable>");
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
- $$ = mtex2MML_copy3("<mstyle mathvariant=\"bold\">", $2, "</mstyle>");
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 compoundTermList ENDENV EQUATION {
2606
- char * n = mtex2MML_global_label();
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 compoundTermList ENDENV EQUATION_STAR {
2613
- $$ = mtex2MML_copy3("<mtable><mlabeledtr><mtd><mtext>&#8239;</mtext></mtd><mtd>", $3, "</mtd></mlabeledtr></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("<mtable><mlabeledtr><mtd>", s2, n);
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("<mtable><mlabeledtr><mtd>", s2, n);
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("<mtable><mlabeledtr><mtd>", s2, n);
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("<mtable><mlabeledtr><mtd>", s2, n);
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("<mtable><mlabeledtr><mtd>", s2, n);
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("<mtable><mlabeledtr><mtd>", s2, n);
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("<mtable><mlabeledtr><mtd>", s2, n);
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("<mtable><mlabeledtr><mtd>", s2, n);
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("<mtable><mlabeledtr><mtd>", s2, n);
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("<mtable><mlabeledtr><mtd>", s2, n);
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
- $$ = mtex2MML_copy3("<mtr>", $1, "</mtr>");
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 https://troydhanson.github.io/uthash/utarray.html#_structures
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->environmentType = src->environmentType;
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
- void env_replacements(UT_array **environment_data_stack, encaseType * encase, const char *environment)
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
- const char *from = "\\begin", *until = "\\end",
11
- *begin_svg = "begin{svg}";
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, from) == NULL && strstr(environment, until) == NULL) || strstr(environment, begin_svg)) {
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 = "", **last_stack_item,
79
+ *temp = "", **prev_stack_item,
24
80
  *a, *em_str;
25
81
 
26
- envType environmentType = OTHER;
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, until) != NULL) {
96
+ if (strstr(line, END) != NULL) {
97
+ envType environment_type = determine_environment(line);
98
+
61
99
  while (utarray_len(array_stack) > 0) {
62
- last_stack_item = (char **)utarray_back(array_stack);
100
+ prev_stack_item = (char **)utarray_back(array_stack);
63
101
 
64
102
  rowlines_stack_len = utarray_len(rowlines_stack);
65
- at_top = strstr(*last_stack_item, from);
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(*last_stack_item, line_separator) == NULL && \
69
- strstr(*last_stack_item, cr_separator) == NULL && \
70
- strstr(*last_stack_item, newline_separator) == NULL) {
71
- if (strstr(*last_stack_item, hline) != NULL || strstr(*last_stack_item, hdashline) != NULL) {
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(*last_stack_item, hline) != NULL) {
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(*last_stack_item, hdashline) != NULL) {
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(*last_stack_item, line_separator) != NULL || \
98
- strstr(*last_stack_item, cr_separator) != NULL || \
99
- strstr(*last_stack_item, newline_separator) != NULL) {
100
- // when an emphasis match, add it...
101
- if ( (tok = strstr(*last_stack_item, em_pattern_begin)) != NULL) {
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, em_pattern_end)) != NULL) {
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 (environmentType == ENV_SMALLMATRIX) {
169
+ if (environment_type == ENV_SMALLMATRIX) {
113
170
  em_str = "0.2em";
114
- } else if (environmentType == ENV_GATHERED) {
171
+ } else if (environment_type == ENV_GATHERED) {
115
172
  em_str = "1.0ex";
116
- } else if (environmentType == ENV_EQNARRAY || environmentType == ENV_ALIGNAT || environmentType == ENV_ALIGNED) {
173
+ } else if (environment_type == ENV_EQNARRAY || environment_type == ENV_ALIGNAT || environment_type == ENV_ALIGNED) {
117
174
  em_str = "3pt";
118
- } else if (environmentType == ENV_MULTLINE) {
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
- if ((rowlines_stack_len != 0 || utarray_len(row_spacing_stack))) {
137
- perform_replacement(environment_data_stack, rowlines_stack, environmentType, row_spacing_stack);
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 environmentType, UT_array *row_spacing_stack)
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
- utarray_pop_back(rowlines_stack);
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 (environmentType == ENV_SMALLMATRIX && strcmp(*p, "0.5ex") == 0) {
261
+ if (environment_type == ENV_SMALLMATRIX && strcmp(*p, "0.5ex") == 0) {
191
262
  utstring_printf(s, "%s ", "0.2em");
192
- } else if (environmentType == ENV_GATHERED && strcmp(*p, "0.5ex") == 0) {
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 (environmentType == ENV_SMALLMATRIX) {
274
+ if (environment_type == ENV_SMALLMATRIX) {
204
275
  attr_rowspacing = "0.2em";
205
- } else if (environmentType == ENV_GATHERED) {
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.environmentType = environmentType;
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->environmentType;
527
+ return row_data_elem->environment_type;
438
528
  }
439
529
 
440
530
  int current_env_line_count(UT_array **environment_data_stack)