mathematical 1.1.1 → 1.2.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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/ext/mathematical/extconf.rb +6 -1
  3. data/ext/mathematical/lasem/src/lsmdomcharacterdata.c +17 -0
  4. data/ext/mathematical/lasem/src/lsmdomdocument.c +17 -0
  5. data/ext/mathematical/lasem/src/lsmmathmlfencedelement.c +8 -6
  6. data/ext/mathematical/lasem/src/lsmmathmloperatorelement.c +8 -6
  7. data/ext/mathematical/lasem/src/lsmmathmlview.c +12 -7
  8. data/ext/mathematical/lasem/src/lsmmathmlview.h +2 -0
  9. data/ext/mathematical/lasem/src/lsmsvgsymbolelement.c +74 -0
  10. data/ext/mathematical/lasem/src/lsmsvgsymbolelement.h +3 -0
  11. data/ext/mathematical/lasem/src/lsmsvguseelement.c +10 -9
  12. data/ext/mathematical/lasem/src/lsmsvgview.c +12 -0
  13. data/ext/mathematical/lasem/src/lsmsvgview.h +1 -0
  14. data/ext/mathematical/lasem/tests/lsmtest.c +1 -1
  15. data/ext/mathematical/lasem/tests/suite.c +18 -1
  16. data/ext/mathematical/mtex2MML/src/lex.yy.c +4454 -4090
  17. data/ext/mathematical/mtex2MML/src/mtex2MML.h +1 -0
  18. data/ext/mathematical/mtex2MML/src/parse_extras.c +176 -41
  19. data/ext/mathematical/mtex2MML/src/parse_extras.h +30 -8
  20. data/ext/mathematical/mtex2MML/src/string_extras.c +5 -26
  21. data/ext/mathematical/mtex2MML/src/string_extras.h +1 -6
  22. data/ext/mathematical/mtex2MML/src/y.tab.c +6600 -5492
  23. data/ext/mathematical/mtex2MML/src/y.tab.h +572 -525
  24. data/lib/mathematical/version.rb +1 -1
  25. data/mathematical.gemspec +1 -1
  26. data/test/mathematical/basic_test.rb +1 -1
  27. data/test/mathematical/corrections_test.rb +1 -1
  28. data/test/mathematical/fixtures_test.rb +1 -1
  29. data/test/mathematical/maliciousness_test.rb +17 -17
  30. data/test/mathematical/mathjax_test.rb +2 -3
  31. data/test/mathematical/mathml_test.rb +1 -1
  32. data/test/mathematical/multiples_test.rb +1 -1
  33. data/test/mathematical/performance_test.rb +6 -8
  34. data/test/mathematical/png_test.rb +1 -1
  35. data/test/test_helper.rb +2 -2
  36. metadata +6 -6
@@ -54,6 +54,7 @@ extern int mtex2MML_lineno;
54
54
 
55
55
  extern int mtex2MML_rowposn;
56
56
  extern int mtex2MML_displaymode;
57
+ extern int display_style;
57
58
 
58
59
  #ifdef __cplusplus
59
60
  }
@@ -7,29 +7,46 @@
7
7
 
8
8
  void env_replacements(UT_array **environment_data_stack, encaseType * encase, const char *environment)
9
9
  {
10
+ const char *from = "\\begin", *until = "\\end",
11
+ *begin_svg = "begin{svg}";
12
+
13
+ // if not an environment, don't bother going on
14
+ if ((strstr(environment, from) == NULL && strstr(environment, until) == NULL) || strstr(environment, begin_svg)) {
15
+ return;
16
+ }
17
+
10
18
  UT_array *array_stack;
11
19
  UT_array *row_spacing_stack;
12
20
  UT_array *rowlines_stack;
13
21
 
14
- char *tok = NULL, *at_top = NULL;
22
+ char *tok = NULL, *at_top = NULL,
23
+ *temp = "", **last_stack_item,
24
+ *a, *em_str;
25
+
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
+ }
15
40
 
16
- char *temp = "", **last_stack_item;
17
- char *a, *em_str;
18
- const char *from = "\\begin", *until = "\\end", *hline = "\\hline", *hdashline = "\\hdashline",
41
+ const char *hline = "\\hline", *hdashline = "\\hdashline",
19
42
  *line_separator = "\\\\",
20
- *cr_separator = "\\cr",
21
- *newline_separator = "\\newline",
22
- *em_pattern_begin = "\\[", *em_pattern_end = "]",
23
- *is_smallmatrix = NULL, *is_gathered = NULL;
43
+ *cr_separator = "\\cr",
44
+ *newline_separator = "\\newline",
45
+ *em_pattern_begin = "\\[", *em_pattern_end = "]";
24
46
 
25
47
  int rowlines_stack_len = 0, em_offset = 0;
26
48
 
27
- // if not an environment, don't bother going on
28
- if ( ((strstr(environment, from) == NULL && strstr(environment, until) == NULL)) || strstr(environment, "begin{svg}")) {
29
- return;
30
- }
31
-
32
- char *dupe_environment = dupe_string(environment);
49
+ char *dupe_environment = strdup(environment);
33
50
  char *line = strtok(dupe_environment, "\n");
34
51
 
35
52
  // set up the array stack
@@ -49,8 +66,8 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
49
66
 
50
67
  // we've reached the top, but there looks like there might be some data
51
68
  if (at_top != NULL && strstr(*last_stack_item, line_separator) == NULL && \
52
- strstr(*last_stack_item, cr_separator) == NULL && \
53
- strstr(*last_stack_item, newline_separator) == NULL) {
69
+ strstr(*last_stack_item, cr_separator) == NULL && \
70
+ strstr(*last_stack_item, newline_separator) == NULL) {
54
71
  if (strstr(*last_stack_item, hline) != NULL || strstr(*last_stack_item, hdashline) != NULL) {
55
72
  *encase = TOPENCLOSE;
56
73
  }
@@ -78,24 +95,28 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
78
95
 
79
96
  // if there's a line break...
80
97
  if (strstr(*last_stack_item, line_separator) != NULL || \
81
- strstr(*last_stack_item, cr_separator) != NULL || \
82
- strstr(*last_stack_item, newline_separator) != NULL) {
98
+ strstr(*last_stack_item, cr_separator) != NULL || \
99
+ strstr(*last_stack_item, newline_separator) != NULL) {
83
100
  // when an emphasis match, add it...
84
101
  if ( (tok = strstr(*last_stack_item, em_pattern_begin)) != NULL) {
85
102
  temp = tok + 2; // skip the first part ("\[")
86
103
  if ( (tok = strstr(temp, em_pattern_end)) != NULL) {
87
104
  em_offset = (int)(tok - temp);
88
- char *s = dupe_string_n(temp, em_offset);
105
+ char *s = strndup(temp, em_offset);
89
106
  utarray_push_back(row_spacing_stack, &s);
90
107
  free(s);
91
108
  }
92
109
  }
93
110
  // otherwise, use the default
94
111
  else {
95
- if (strstr(*last_stack_item, "\\begin{smallmatrix}") != NULL) {
112
+ if (environmentType == ENV_SMALLMATRIX) {
96
113
  em_str = "0.2em";
97
- } else if (strstr(*last_stack_item, "\\begin{gathered}") != NULL) {
114
+ } else if (environmentType == ENV_GATHERED) {
98
115
  em_str = "1.0ex";
116
+ } else if (environmentType == ENV_EQNARRAY || environmentType == ENV_ALIGNAT || environmentType == ENV_ALIGNED) {
117
+ em_str = "3pt";
118
+ } else if (environmentType == ENV_MULTLINE) {
119
+ em_str = "0.5em";
99
120
  } else {
100
121
  em_str = "0.5ex";
101
122
  }
@@ -111,13 +132,9 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
111
132
  break;
112
133
  }
113
134
  }
114
- if (at_top != NULL) {
115
- is_smallmatrix = strstr(at_top, "\\begin{smallmatrix}");
116
- is_gathered = strstr(at_top, "\\begin{gathered}");
117
- }
118
135
 
119
136
  if ((rowlines_stack_len != 0 || utarray_len(row_spacing_stack))) {
120
- perform_replacement(environment_data_stack, rowlines_stack, is_smallmatrix, is_gathered, row_spacing_stack);
137
+ perform_replacement(environment_data_stack, rowlines_stack, environmentType, row_spacing_stack);
121
138
  }
122
139
 
123
140
  utarray_clear(row_spacing_stack);
@@ -134,16 +151,18 @@ void env_replacements(UT_array **environment_data_stack, encaseType * encase, co
134
151
  free(dupe_environment);
135
152
  }
136
153
 
137
- void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_stack, const char *is_smallmatrix, const char *is_gathered, UT_array *row_spacing_stack)
154
+ void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_stack, envType environmentType, UT_array *row_spacing_stack)
138
155
  {
139
156
  char *a, *attr_rowlines, *attr_rowspacing;
140
- envdata_t row_data;
157
+ envdata_t env_data;
141
158
 
142
159
  // we cut the last char because we can always skip the first row
143
160
  utarray_pop_back(rowlines_stack);
144
161
 
162
+ int line_count = utarray_len(rowlines_stack);
163
+
145
164
  // empty rowlines should be reset
146
- if (utarray_len(rowlines_stack) == 0) {
165
+ if (line_count == 0) {
147
166
  a = "none";
148
167
  utarray_push_back(rowlines_stack, &a);
149
168
  }
@@ -168,9 +187,9 @@ void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_s
168
187
  utstring_new(s);
169
188
  char **p=NULL;
170
189
  while ( (p=(char**)utarray_prev(row_spacing_stack,p))) {
171
- if (is_smallmatrix && strcmp(*p, "0.5ex") == 0) {
190
+ if (environmentType == ENV_SMALLMATRIX && strcmp(*p, "0.5ex") == 0) {
172
191
  utstring_printf(s, "%s ", "0.2em");
173
- } else if (is_gathered && strcmp(*p, "0.5ex") == 0) {
192
+ } else if (environmentType == ENV_GATHERED && strcmp(*p, "0.5ex") == 0) {
174
193
  utstring_printf(s, "%s ", "1.0ex");
175
194
  } else {
176
195
  utstring_printf(s, "%s ", *p);
@@ -181,26 +200,29 @@ void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_s
181
200
  if (strlen(attr_rowspacing) > 0) {
182
201
  remove_last_char(attr_rowspacing); // remove the final space
183
202
  } else {
184
- if (is_smallmatrix != NULL) {
203
+ if (environmentType == ENV_SMALLMATRIX) {
185
204
  attr_rowspacing = "0.2em";
186
- } else if (is_gathered != NULL) {
205
+ } else if (environmentType == ENV_GATHERED) {
187
206
  attr_rowspacing = "1.0ex";
188
207
  } else {
189
208
  attr_rowspacing = "0.5ex";
190
209
  }
191
210
  }
192
211
 
193
- row_data.rowspacing = attr_rowspacing;
194
- row_data.rowlines = attr_rowlines;
212
+ // store pertinent metadata
213
+ env_data.rowspacing = attr_rowspacing;
214
+ env_data.rowlines = attr_rowlines;
215
+ env_data.environmentType = environmentType;
216
+ env_data.line_count = line_count;
195
217
 
196
- utarray_push_back(*environment_data_stack, &row_data);
218
+ utarray_push_back(*environment_data_stack, &env_data);
197
219
  utstring_free(l);
198
220
  utstring_free(s);
199
221
  }
200
222
 
201
223
  const char *vertical_pipe_extract(const char *string)
202
224
  {
203
- char *dupe = dupe_string(string);
225
+ char *dupe = strdup(string);
204
226
  UT_string *columnlines, *border;
205
227
  char *previous_column = "", *attr_columnlines, *attr_border;
206
228
  int i = 0;
@@ -253,9 +275,10 @@ const char *vertical_pipe_extract(const char *string)
253
275
  utstring_printf(columnlines, "%s", "none");
254
276
  }
255
277
 
256
- attr_columnlines = utstring_body(columnlines);
278
+ attr_columnlines = strdup(utstring_body(columnlines));
257
279
  free(dupe);
258
280
  utstring_free(border);
281
+ utstring_free(columnlines);
259
282
 
260
283
  return attr_columnlines;
261
284
  }
@@ -265,7 +288,7 @@ const char *remove_excess_pipe_chars(const char *string)
265
288
  UT_string *columnalign;
266
289
  utstring_new(columnalign);
267
290
 
268
- char *dupe = dupe_string(string);
291
+ char *dupe = strdup(string);
269
292
  char *token = strtok(dupe, " ");
270
293
  char *attr_columnalign;
271
294
 
@@ -276,8 +299,9 @@ const char *remove_excess_pipe_chars(const char *string)
276
299
  token = strtok(NULL, " ");
277
300
  }
278
301
 
279
- attr_columnalign = utstring_body(columnalign);
302
+ attr_columnalign = strdup(utstring_body(columnalign));
280
303
  free(dupe);
304
+ utstring_free(columnalign);
281
305
 
282
306
  if (strlen(attr_columnalign) > 0) {
283
307
  remove_last_char(attr_columnalign); // remove the final space
@@ -307,8 +331,119 @@ const char *combine_row_data(UT_array **environment_data_stack)
307
331
  // combine the row spacing and row lines data
308
332
  utstring_printf(row_attr_data, "%s%s\" %s\"", "rowspacing=\"", row_spacing_data, row_lines_data);
309
333
 
310
- row_attr = dupe_string(utstring_body(row_attr_data));
334
+ row_attr = strdup(utstring_body(row_attr_data));
311
335
  utarray_erase(*environment_data_stack, 0, 1);
312
336
 
337
+ utstring_free(row_attr_data);
338
+
313
339
  return row_attr;
314
340
  }
341
+
342
+ const float extract_number_from_pxstring(const char * str)
343
+ {
344
+ float dbl;
345
+ int match = 0;
346
+
347
+ match = sscanf (str, "%*[^-0123456789]%f", &dbl);
348
+ if (match == 1) {
349
+ return dbl;
350
+ }
351
+
352
+ // must not be a float.
353
+ sscanf (str, "%d", &match);
354
+ return (float) match;
355
+ }
356
+
357
+ const char *extract_string_from_pxstring(const char * str)
358
+ {
359
+ char *pixel;
360
+ float dbl;
361
+ pixel = malloc(3*sizeof(char));
362
+ sscanf (str, "%f%s", &dbl, pixel);
363
+ return pixel;
364
+ }
365
+
366
+ const char * dbl2em(const char *str)
367
+ {
368
+ UT_string *em;
369
+ utstring_new(em);
370
+
371
+ float dbl = extract_number_from_pxstring(str);
372
+ dbl *= 0.056;
373
+
374
+ utstring_printf(em, "%.3fem", dbl);
375
+ char * em_str = strdup(utstring_body(em));
376
+
377
+ utstring_free(em);
378
+
379
+ return em_str;
380
+ }
381
+
382
+ const char * double_pixel(float f, char *pixel)
383
+ {
384
+ UT_string *em;
385
+ utstring_new(em);
386
+
387
+ float dbl = f * 2;
388
+ utstring_printf(em, "%.3f%s", dbl, pixel);
389
+ char * em_str = strdup(utstring_body(em));
390
+
391
+ utstring_free(em);
392
+
393
+ return em_str;
394
+ }
395
+
396
+ const char * implement_skew(char *base_str, char *em_skew, char *pattern)
397
+ {
398
+ UT_string *skew_mathml;
399
+ utstring_new(skew_mathml);
400
+
401
+ utstring_printf(skew_mathml, "%s%s%s", "<mrow><mrow><mrow><mover><mrow>", base_str, "<mspace width=\"");
402
+ utstring_printf(skew_mathml, "%s%s%s", em_skew, "\" /></mrow>", "<mo stretchy=\"false\">");
403
+ utstring_printf(skew_mathml, "%s%s%s", pattern, "</mo></mover></mrow><mspace width=\"-", em_skew);
404
+ utstring_printf(skew_mathml, "%s", "\" /></mrow><mrow></mrow></mrow>");
405
+
406
+ char * skew_mathml_str = strdup(utstring_body(skew_mathml));
407
+
408
+ utstring_free(skew_mathml);
409
+
410
+ return skew_mathml_str;
411
+ }
412
+
413
+ const char * root_pos_to_em(const char * str)
414
+ {
415
+ UT_string *em;
416
+ utstring_new(em);
417
+
418
+ float dbl = extract_number_from_pxstring(str);
419
+ dbl /= 15;
420
+
421
+ utstring_printf(em, "%.3fem", dbl);
422
+ char * em_str = strdup(utstring_body(em));
423
+
424
+ utstring_free(em);
425
+
426
+ return em_str;
427
+ }
428
+
429
+ envType current_env_type(UT_array **environment_data_stack)
430
+ {
431
+ if (utarray_len(*environment_data_stack) == 0) {
432
+ return -1;
433
+ }
434
+
435
+ envdata_t *row_data_elem = (envdata_t*) utarray_front(*environment_data_stack);
436
+
437
+ return row_data_elem->environmentType;
438
+ }
439
+
440
+ int current_env_line_count(UT_array **environment_data_stack)
441
+ {
442
+ if (utarray_len(*environment_data_stack) == 0) {
443
+ return -1;
444
+ }
445
+
446
+ envdata_t *row_data_elem = (envdata_t*) utarray_front(*environment_data_stack);
447
+
448
+ return row_data_elem->line_count;
449
+ }
@@ -9,18 +9,15 @@ extern "C" {
9
9
  #endif
10
10
 
11
11
  typedef enum {NONE = 0, TOPENCLOSE} encaseType;
12
+ typedef enum {OTHER = 0, ENV_ALIGNAT, ENV_ALIGNED, ENV_GATHERED, ENV_EQNARRAY, ENV_MULTLINE, ENV_SMALLMATRIX} envType;
12
13
 
13
14
  typedef struct {
14
15
  char *rowspacing;
15
16
  char *rowlines;
16
- int empty;
17
+ envType environmentType;
18
+ int line_count;
17
19
  } envdata_t;
18
20
 
19
- typedef struct {
20
- char *attribute;
21
- int offset_pos;
22
- } symbolData;
23
-
24
21
  struct css_colors {
25
22
  char name[22]; /* key */
26
23
  char color[10];
@@ -58,11 +55,11 @@ struct css_colors {
58
55
  //
59
56
  // The env_replacements function will push every line onto a stack. When an \end
60
57
  // is detected, it starts popping off the stack until it reaches the corresponding
61
- // \begin. It then modifies that stack with attribute strings, an arrangement of the
58
+ // \begin. It then modifies that stack with attribute strings, an arrangement of
62
59
  // the symbols encountered while popping lines off.
63
60
  extern void env_replacements(UT_array **environment_data_stack, encaseType *encase, const char *environment);
64
61
 
65
- extern void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_stack, const char *is_smallmatrix, const char *is_gathered, UT_array *row_spacing_stack);
62
+ extern void perform_replacement(UT_array **environment_data_stack, UT_array *rowlines_stack, envType environmentType, UT_array *row_spacing_stack);
66
63
 
67
64
  // determines the column border arrangement from the array environment definition (c|cc|c...)
68
65
  extern const char *vertical_pipe_extract(const char *string);
@@ -74,6 +71,31 @@ extern const char *remove_excess_pipe_chars(const char *string);
74
71
  // return the proper rowlines information
75
72
  extern const char *combine_row_data(UT_array **environment_data_stack);
76
73
 
74
+ // given a pixel string, retrieve the numeric portion from it
75
+ extern const float extract_number_from_pxstring(const char * str);
76
+
77
+ // given a pixel string, retrieve the pixel type portion from it
78
+ extern const char *extract_string_from_pxstring(const char * str);
79
+
80
+ // given a number, return it as an em
81
+ extern const char * dbl2em(const char *str);
82
+
83
+ // given a number, return it as a root position
84
+ // taken straight from MathJax
85
+ extern const char * root_pos_to_em(const char * str);
86
+
87
+ // given a number and a pixel string, return the doubled number
88
+ extern const char * double_pixel(float f, char *pixel);
89
+
90
+ // construct a skew sequence
91
+ extern const char * implement_skew(char *base_str, char *em_skew, char *pattern);
92
+
93
+ // get the environment type of the top-most item
94
+ extern envType current_env_type(UT_array **environment_data_stack);
95
+
96
+ // get the line count of the top-most item
97
+ extern int current_env_line_count(UT_array **environment_data_stack);
98
+
77
99
  #ifdef __cplusplus
78
100
  }
79
101
  #endif
@@ -15,24 +15,6 @@ void remove_first_char(char* str)
15
15
  memmove(str, str + 1, len);
16
16
  }
17
17
 
18
- char *dupe_string(const char * str)
19
- {
20
- int len = strlen(str) + 1;
21
- char *buf = malloc(len);
22
- if (buf) { memcpy(buf, str, len); }
23
- return buf;
24
- }
25
-
26
- char *dupe_string_n(const char *s, size_t n)
27
- {
28
- char* buf = malloc(n + 1);
29
- if (buf) {
30
- strncpy(buf, s, n);
31
- buf[n] = '\0';
32
- }
33
- return buf;
34
- }
35
-
36
18
  char * str_replace (char *string, const char *substr, const char *replacement)
37
19
  {
38
20
  char *tok = NULL;
@@ -41,22 +23,19 @@ char * str_replace (char *string, const char *substr, const char *replacement)
41
23
 
42
24
  /* if either substr or replacement is NULL, duplicate string a let caller handle it */
43
25
 
44
- if ( substr == NULL || replacement == NULL )
45
- {
46
- return dupe_string (string);
26
+ if ( substr == NULL || replacement == NULL ) {
27
+ return strdup(string);
47
28
  }
48
29
 
49
- newstr = dupe_string (string);
30
+ newstr = strdup(string);
50
31
 
51
- while ( ( tok = strstr( newstr, substr ) ) )
52
- {
32
+ while ( ( tok = strstr( newstr, substr ) ) ) {
53
33
 
54
34
  oldstr = newstr;
55
35
  newstr = malloc ( strlen ( oldstr ) - strlen ( substr ) + strlen ( replacement ) + 1 );
56
36
 
57
37
  /* If failed to alloc mem, free old string and return NULL */
58
- if ( newstr == NULL )
59
- {
38
+ if ( newstr == NULL ) {
60
39
  free (oldstr);
61
40
  return NULL;
62
41
  }