mathematical 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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)