mathematical 1.1.1 → 1.2.0

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