rmultimarkdown 6.4.0.4 → 6.7.0.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 (76) hide show
  1. checksums.yaml +5 -5
  2. data/Rakefile +7 -13
  3. data/ext/Makefile +67 -55
  4. data/ext/extconf.rb +7 -5
  5. data/ext/mmd/aho-corasick.c +8 -8
  6. data/ext/mmd/aho-corasick.h +3 -3
  7. data/ext/mmd/argtable3.c +6537 -0
  8. data/ext/mmd/argtable3.h +273 -0
  9. data/ext/mmd/beamer.c +12 -1
  10. data/ext/mmd/char.c +120 -27
  11. data/ext/mmd/char.h +23 -23
  12. data/ext/mmd/critic_markup.c +7 -6
  13. data/ext/mmd/d_string.c +88 -32
  14. data/ext/mmd/{include/d_string.h → d_string.h} +50 -38
  15. data/ext/mmd/epub.c +36 -12
  16. data/ext/mmd/epub.h +2 -2
  17. data/ext/mmd/file.c +50 -40
  18. data/ext/mmd/file.h +2 -2
  19. data/ext/mmd/html.c +164 -99
  20. data/ext/mmd/html.h +3 -2
  21. data/ext/mmd/i18n.h +15 -11
  22. data/ext/mmd/itmz-lexer.c +16978 -0
  23. data/ext/mmd/itmz-lexer.h +132 -0
  24. data/ext/mmd/itmz-parser.c +1189 -0
  25. data/ext/mmd/itmz-parser.h +11 -0
  26. data/ext/mmd/itmz-reader.c +388 -0
  27. data/ext/mmd/itmz-reader.h +111 -0
  28. data/ext/mmd/itmz.c +567 -0
  29. data/ext/mmd/itmz.h +117 -0
  30. data/ext/mmd/latex.c +93 -41
  31. data/ext/mmd/lexer.c +3506 -2774
  32. data/ext/mmd/{include/libMultiMarkdown.h → libMultiMarkdown.h} +49 -2
  33. data/ext/mmd/main.c +612 -0
  34. data/ext/mmd/memoir.c +4 -1
  35. data/ext/mmd/miniz.c +6905 -6680
  36. data/ext/mmd/miniz.h +456 -476
  37. data/ext/mmd/mmd.c +399 -94
  38. data/ext/mmd/mmd.h +25 -25
  39. data/ext/mmd/object_pool.h +3 -3
  40. data/ext/mmd/opendocument-content.c +137 -69
  41. data/ext/mmd/opendocument-content.h +2 -2
  42. data/ext/mmd/opendocument.c +35 -14
  43. data/ext/mmd/opendocument.h +2 -2
  44. data/ext/mmd/opml-lexer.c +259 -637
  45. data/ext/mmd/opml-lexer.h +1 -17
  46. data/ext/mmd/opml-parser.c +194 -188
  47. data/ext/mmd/opml-reader.c +72 -142
  48. data/ext/mmd/opml-reader.h +1 -1
  49. data/ext/mmd/opml.c +13 -13
  50. data/ext/mmd/opml.h +1 -1
  51. data/ext/mmd/parser.c +1623 -1244
  52. data/ext/mmd/rng.c +8 -3
  53. data/ext/mmd/scanners.c +66625 -103198
  54. data/ext/mmd/scanners.h +1 -0
  55. data/ext/mmd/stack.c +62 -20
  56. data/ext/mmd/stack.h +10 -21
  57. data/ext/mmd/textbundle.c +23 -7
  58. data/ext/mmd/textbundle.h +2 -2
  59. data/ext/mmd/token.c +42 -16
  60. data/ext/mmd/{include/token.h → token.h} +22 -8
  61. data/ext/mmd/token_pairs.c +0 -16
  62. data/ext/mmd/transclude.c +6 -2
  63. data/ext/mmd/uthash.h +745 -745
  64. data/ext/mmd/version.h +8 -8
  65. data/ext/mmd/writer.c +225 -63
  66. data/ext/mmd/writer.h +50 -36
  67. data/ext/mmd/xml.c +855 -0
  68. data/ext/mmd/xml.h +134 -0
  69. data/ext/mmd/zip.c +71 -4
  70. data/ext/mmd/zip.h +7 -1
  71. data/ext/ruby_multi_markdown.c +9 -18
  72. data/lib/multi_markdown/version.rb +1 -1
  73. data/lib/multi_markdown.bundle +0 -0
  74. data/rmultimarkdown.gemspec +0 -2
  75. metadata +22 -28
  76. data/ext/mmd/char_lookup.c +0 -212
data/ext/mmd/scanners.h CHANGED
@@ -76,6 +76,7 @@ size_t scan_atx(const char * c);
76
76
  size_t scan_definition(const char * c);
77
77
  size_t scan_destination(const char * c);
78
78
  size_t scan_email(const char * c);
79
+ size_t scan_empty_meta_line(const char * c);
79
80
  size_t scan_fence_start(const char * c);
80
81
  size_t scan_fence_end(const char * c);
81
82
  size_t scan_html(const char * c);
data/ext/mmd/stack.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
 
3
- MultiMarkdown 6 -- Lightweight markup processor to produce HTML, LaTeX, and more.
3
+ libCoreUtilities -- Reusable component libraries
4
4
 
5
5
  @file stack.c
6
6
 
@@ -14,23 +14,12 @@
14
14
 
15
15
  /*
16
16
 
17
- Copyright © 2016 - 2017 Fletcher T. Penney.
17
+ Copyright © 2016-2020 Fletcher T. Penney.
18
18
 
19
19
 
20
- The `MultiMarkdown 6` project is released under the MIT License..
20
+ MIT License
21
21
 
22
- GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project:
23
-
24
- https://github.com/fletcher/MultiMarkdown-4/
25
-
26
- MMD 4 is released under both the MIT License and GPL.
27
-
28
-
29
- CuTest is released under the zlib/libpng license. See CuTest.c for the text
30
- of the license.
31
-
32
-
33
- ## The MIT License ##
22
+ Copyright (c) 2016-2020 Fletcher T. Penney
34
23
 
35
24
  Permission is hereby granted, free of charge, to any person obtaining a copy
36
25
  of this software and associated documentation files (the "Software"), to deal
@@ -39,24 +28,28 @@
39
28
  copies of the Software, and to permit persons to whom the Software is
40
29
  furnished to do so, subject to the following conditions:
41
30
 
42
- The above copyright notice and this permission notice shall be included in
43
- all copies or substantial portions of the Software.
31
+ The above copyright notice and this permission notice shall be included in all
32
+ copies or substantial portions of the Software.
44
33
 
45
34
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46
35
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47
36
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48
37
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49
38
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51
- THE SOFTWARE.
39
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
40
+ SOFTWARE.
52
41
 
53
- */
42
+ */
54
43
 
55
44
  #include <stdlib.h>
56
45
  #include <string.h>
57
46
 
58
47
  #include "stack.h"
59
48
 
49
+ #ifdef TEST
50
+ #include "CuTest.h"
51
+ #endif
52
+
60
53
  #define kStackStartingSize 64
61
54
 
62
55
 
@@ -94,6 +87,26 @@ void stack_free(stack * s) {
94
87
  }
95
88
 
96
89
 
90
+ #ifdef TEST
91
+ void Test_stack_new(CuTest * tc) {
92
+ stack * s = stack_new(0);
93
+ CuAssertIntEquals(tc, kStackStartingSize, s->capacity);
94
+ CuAssertIntEquals(tc, 0, s->size);
95
+ stack_free(s);
96
+
97
+ s = stack_new(-1);
98
+ CuAssertIntEquals(tc, kStackStartingSize, s->capacity);
99
+ CuAssertIntEquals(tc, 0, s->size);
100
+ stack_free(s);
101
+
102
+ s = stack_new(10);
103
+ CuAssertIntEquals(tc, 10, s->capacity);
104
+ CuAssertIntEquals(tc, 0, s->size);
105
+ stack_free(s);
106
+ }
107
+ #endif
108
+
109
+
97
110
  /// Add a new pointer to the stack
98
111
  void stack_push(stack * s, void * element) {
99
112
  if (s->size == s->capacity) {
@@ -137,6 +150,35 @@ void * stack_peek_index(stack * s, size_t index) {
137
150
  }
138
151
 
139
152
 
153
+ #ifdef TEST
154
+ void Test_stack_push_pop(CuTest * tc) {
155
+ stack * s = stack_new(1);
156
+
157
+ char * s1 = "foo";
158
+ char * s2 = "bar";
159
+ char * s3 = "bat";
160
+
161
+ stack_push(s, s1);
162
+ stack_push(s, s2);
163
+ stack_push(s, s3);
164
+
165
+ CuAssertIntEquals(tc, 3, s->size);
166
+ CuAssertIntEquals(tc, 4, s->capacity);
167
+
168
+ CuAssertStrEquals(tc, "bat", stack_peek(s));
169
+ CuAssertStrEquals(tc, "foo", stack_peek_index(s, 0));
170
+
171
+ CuAssertStrEquals(tc, "bat", stack_pop(s));
172
+ CuAssertStrEquals(tc, "bar", stack_pop(s));
173
+ CuAssertStrEquals(tc, "foo", stack_pop(s));
174
+
175
+ CuAssertIntEquals(tc, 0, s->size);
176
+
177
+ stack_free(s);
178
+ }
179
+ #endif
180
+
181
+
140
182
  /// Sort array using specified compare_function
141
183
  void stack_sort(stack * s, void * compare_function) {
142
184
  qsort(s->element, s->size, sizeof(void *), compare_function);
data/ext/mmd/stack.h CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
 
3
- MultiMarkdown 6 -- Lightweight markup processor to produce HTML, LaTeX, and more.
3
+ libCoreUtilities -- Reusable component libraries
4
4
 
5
5
  @file stack.h
6
6
 
@@ -14,23 +14,12 @@
14
14
 
15
15
  /*
16
16
 
17
- Copyright © 2016 - 2017 Fletcher T. Penney.
17
+ Copyright © 2016-2020 Fletcher T. Penney.
18
18
 
19
19
 
20
- The `MultiMarkdown 6` project is released under the MIT License..
20
+ MIT License
21
21
 
22
- GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project:
23
-
24
- https://github.com/fletcher/MultiMarkdown-4/
25
-
26
- MMD 4 is released under both the MIT License and GPL.
27
-
28
-
29
- CuTest is released under the zlib/libpng license. See CuTest.c for the text
30
- of the license.
31
-
32
-
33
- ## The MIT License ##
22
+ Copyright (c) 2016-2020 Fletcher T. Penney
34
23
 
35
24
  Permission is hereby granted, free of charge, to any person obtaining a copy
36
25
  of this software and associated documentation files (the "Software"), to deal
@@ -39,18 +28,18 @@
39
28
  copies of the Software, and to permit persons to whom the Software is
40
29
  furnished to do so, subject to the following conditions:
41
30
 
42
- The above copyright notice and this permission notice shall be included in
43
- all copies or substantial portions of the Software.
31
+ The above copyright notice and this permission notice shall be included in all
32
+ copies or substantial portions of the Software.
44
33
 
45
34
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46
35
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47
36
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48
37
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49
38
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51
- THE SOFTWARE.
39
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
40
+ SOFTWARE.
52
41
 
53
- */
42
+ */
54
43
 
55
44
 
56
45
  #ifndef STACK_SMART_STRING_H
@@ -62,7 +51,7 @@
62
51
  struct stack {
63
52
  size_t size; //!< Number of objects currently in stack
64
53
  size_t capacity; //!< Total current capacity for stack
65
- void ** element; //!< Array of pointers to objects in stack
54
+ void ** element; //!< Array of pointers to objects in stack
66
55
  };
67
56
 
68
57
  typedef struct stack stack;
data/ext/mmd/textbundle.c CHANGED
@@ -105,13 +105,30 @@
105
105
  #include <stdlib.h>
106
106
  #include <sys/stat.h>
107
107
 
108
+ #ifdef __APPLE__
109
+ #include "TargetConditionals.h"
110
+ #if TARGET_IPHONE_SIMULATOR
111
+ // iOS Simulator
112
+ #undef USE_CURL
113
+ #elif TARGET_OS_IPHONE
114
+ // iOS device
115
+ #undef USE_CURL
116
+ #elif TARGET_OS_MAC
117
+ // Other kinds of Mac OS
118
+ #else
119
+ # error "Unknown Apple platform"
120
+ #endif
121
+ #endif
122
+
108
123
  #ifdef USE_CURL
109
124
  #include <curl/curl.h>
110
125
  #endif
111
126
 
112
127
  #include "file.h"
113
128
  #include "miniz.h"
129
+ #include "stack.h"
114
130
  #include "textbundle.h"
131
+ #include "token.h"
115
132
  #include "writer.h"
116
133
  #include "zip.h"
117
134
 
@@ -222,7 +239,7 @@ static void add_assets(mz_zip_archive * pZip, mmd_engine * e, const char * direc
222
239
  if (res != CURLE_OK) {
223
240
  // Attempt to add asset from local file
224
241
  if (!add_asset_from_file(pZip, a, destination, directory)) {
225
- fprintf(stderr, "Unable to store '%s' in EPUB\n", a->url);
242
+ fprintf(stderr, "Unable to store '%s' in TextBundle\n", a->url);
226
243
  }
227
244
  } else {
228
245
  // Store downloaded file in zip
@@ -252,7 +269,7 @@ static void add_assets(mz_zip_archive * pZip, mmd_engine * e, const char * direc
252
269
 
253
270
  // Attempt to add asset from local file
254
271
  if (!add_asset_from_file(pZip, a, destination, directory)) {
255
- fprintf(stderr, "Unable to store '%s' in EPUB\n", a->url);
272
+ fprintf(stderr, "Unable to store '%s' in TextBundle\n", a->url);
256
273
  }
257
274
  }
258
275
  }
@@ -273,7 +290,7 @@ void traverse_for_images(token * t, DString * text, mmd_engine * e, long * offse
273
290
 
274
291
  memcpy(url, &text->str[t->start + *offset + 1], t->len - 2);
275
292
  url[t->len - 2] = '\0';
276
- clean = clean_string(url, false);
293
+ clean = clean_string(url, false, true);
277
294
 
278
295
  HASH_FIND_STR(e->asset_hash, clean, a);
279
296
 
@@ -367,7 +384,7 @@ void sub_asset_paths(DString * text, mmd_engine * e) {
367
384
  }
368
385
 
369
386
 
370
- DString * textbundle_create(const char * body, mmd_engine * e, const char * directory) {
387
+ DString * textbundle_create(DString * body, mmd_engine * e, const char * directory) {
371
388
  DString * result = d_string_new("");
372
389
  scratch_pad * scratch = scratch_pad_new(e, FORMAT_TEXTBUNDLE_COMPRESSED);
373
390
 
@@ -409,8 +426,7 @@ DString * textbundle_create(const char * body, mmd_engine * e, const char * dire
409
426
  }
410
427
 
411
428
  // Add html version document
412
- len = strlen(body);
413
- status = mz_zip_writer_add_mem(&zip, "text.html", body, len, MZ_BEST_COMPRESSION);
429
+ status = mz_zip_writer_add_mem(&zip, "text.html", body->str, body->currentStringLength, MZ_BEST_COMPRESSION);
414
430
 
415
431
  if (!status) {
416
432
  fprintf(stderr, "Error adding content to zip.\n");
@@ -436,7 +452,7 @@ DString * textbundle_create(const char * body, mmd_engine * e, const char * dire
436
452
 
437
453
 
438
454
  // Use the miniz library to create a zip archive for the TEXTBUNDLE_COMPRESSED document
439
- void textbundle_write_wrapper(const char * filepath, const char * body, mmd_engine * e, const char * directory) {
455
+ void textbundle_write_wrapper(const char * filepath, DString * body, mmd_engine * e, const char * directory) {
440
456
  FILE * output_stream;
441
457
 
442
458
  DString * result = textbundle_create(body, e, directory);
data/ext/mmd/textbundle.h CHANGED
@@ -108,8 +108,8 @@
108
108
  #include "d_string.h"
109
109
  #include "mmd.h"
110
110
 
111
- void textbundle_write_wrapper(const char * filepath, const char * body, mmd_engine * e, const char * directory);
111
+ void textbundle_write_wrapper(const char * filepath, DString * body, mmd_engine * e, const char * directory);
112
112
 
113
- DString * textbundle_create(const char * body, mmd_engine * e, const char * directory);
113
+ DString * textbundle_create(DString * body, mmd_engine * e, const char * directory);
114
114
 
115
115
  #endif
data/ext/mmd/token.c CHANGED
@@ -115,17 +115,20 @@ void token_pool_free(void) {
115
115
  token * token_new(unsigned short type, size_t start, size_t len) {
116
116
 
117
117
 
118
- #ifdef kUseObjectPool
118
+ #ifdef kUseObjectPool
119
119
  token * t = pool_allocate_object(token_pool);
120
- #else
120
+ #else
121
121
  token * t = malloc(sizeof(token));
122
- #endif
122
+ #endif
123
123
 
124
124
  if (t) {
125
125
  t->type = type;
126
126
  t->start = start;
127
127
  t->len = len;
128
128
 
129
+ t->out_start = 0;
130
+ t->out_len = 0;
131
+
129
132
  t->next = NULL;
130
133
  t->prev = NULL;
131
134
  t->child = NULL;
@@ -145,11 +148,11 @@ token * token_new(unsigned short type, size_t start, size_t len) {
145
148
 
146
149
  /// Duplicate an existing token
147
150
  token * token_copy(token * original) {
148
- #ifdef kUseObjectPool
151
+ #ifdef kUseObjectPool
149
152
  token * t = pool_allocate_object(token_pool);
150
- #else
153
+ #else
151
154
  token * t = malloc(sizeof(token));
152
- #endif
155
+ #endif
153
156
 
154
157
  if (t) {
155
158
  * t = * original;
@@ -276,9 +279,28 @@ void token_remove_tail(token * head) {
276
279
  }
277
280
 
278
281
 
282
+ /// Fix tail at head of token chain (e.g. after pruning)
283
+ void fix_token_chain_tail(token * t) {
284
+ if (t) {
285
+ token * head = t;
286
+
287
+ // Find head of chain
288
+ while (head->prev) {
289
+ head = head->prev;
290
+ }
291
+
292
+ // Find tail
293
+ while (t->next) {
294
+ t = t->next;
295
+ }
296
+
297
+ // Fix tail
298
+ head->tail = t;
299
+ }
300
+ }
301
+
279
302
  /// Pop token out of it's chain, connecting head and tail of chain back together.
280
303
  /// Token must be freed if it is no longer needed.
281
- /// \todo: If t is the tail token of a chain, the tail is no longer correct on the start of chain.
282
304
  void token_pop_link_from_chain(token * t) {
283
305
  if (t == NULL) {
284
306
  return;
@@ -293,6 +315,8 @@ void token_pop_link_from_chain(token * t) {
293
315
 
294
316
  if (prev) {
295
317
  prev->next = next;
318
+
319
+ fix_token_chain_tail(prev);
296
320
  }
297
321
 
298
322
  if (next) {
@@ -312,6 +336,8 @@ void tokens_prune(token * first, token * last) {
312
336
 
313
337
  if (prev != NULL) {
314
338
  prev->next = next;
339
+
340
+ fix_token_chain_tail(prev);
315
341
  }
316
342
 
317
343
  if (next != NULL) {
@@ -387,9 +413,9 @@ token * token_prune_graft(token * first, token * last, unsigned short container_
387
413
 
388
414
  /// Free token
389
415
  void token_free(token * t) {
390
- #ifdef kUseObjectPool
416
+ #ifdef kUseObjectPool
391
417
  return;
392
- #else
418
+ #else
393
419
 
394
420
  if (t == NULL) {
395
421
  return;
@@ -398,15 +424,15 @@ void token_free(token * t) {
398
424
  token_tree_free(t->child);
399
425
 
400
426
  free(t);
401
- #endif
427
+ #endif
402
428
  }
403
429
 
404
430
 
405
431
  /// Free token chain
406
432
  void token_tree_free(token * t) {
407
- #ifdef kUseObjectPool
433
+ #ifdef kUseObjectPool
408
434
  return;
409
- #else
435
+ #else
410
436
  token * n;
411
437
 
412
438
  while (t != NULL) {
@@ -416,7 +442,7 @@ void token_tree_free(token * t) {
416
442
  t = n;
417
443
  }
418
444
 
419
- #endif
445
+ #endif
420
446
  }
421
447
 
422
448
 
@@ -592,7 +618,7 @@ void token_trim_leading_whitespace(token * t, const char * string) {
592
618
 
593
619
 
594
620
  void token_trim_trailing_whitespace(token * t, const char * string) {
595
- while (t->len && char_is_whitespace(string[t->start + t->len - 1])) {
621
+ while (t->len && char_is_whitespace_or_line_ending(string[t->start + t->len - 1])) {
596
622
  t->len--;
597
623
  }
598
624
  }
@@ -606,7 +632,7 @@ void token_trim_whitespace(token * t, const char * string) {
606
632
 
607
633
  /// Check whether first token in the chain matches the given type.
608
634
  /// If so, return and advance the chain.
609
- token * token_chain_accept(token ** t, short type) {
635
+ token * token_chain_accept(token ** t, unsigned short type) {
610
636
  token * result = NULL;
611
637
 
612
638
  if (t && *t && ((*t)->type == type)) {
@@ -639,7 +665,7 @@ token * token_chain_accept_multiple(token ** t, int n, ...) {
639
665
  }
640
666
 
641
667
 
642
- void token_skip_until_type(token ** t, short type) {
668
+ void token_skip_until_type(token ** t, unsigned short type) {
643
669
  while ((*t) && ((*t)->type != type)) {
644
670
  *t = (*t)->next;
645
671
  }
@@ -58,7 +58,12 @@
58
58
  #define TOKEN_PARSER_TEMPLATE_H
59
59
 
60
60
 
61
- #define kUseObjectPoolDisabled 1 //!< Use an object pool to allocate tokens to improve
61
+ #ifdef DISABLE_OBJECT_POOL
62
+ #undef kUseObjectPool
63
+ #else
64
+ #define kUseObjectPool 1
65
+ #endif
66
+ //!< Use an object pool to allocate tokens to improve
62
67
  //!< performance in memory allocation. Frees all
63
68
  //!< tokens at once, however, at end of parsing.
64
69
 
@@ -66,6 +71,12 @@
66
71
  /// This allows us to know when the pool is no longer being used and it is safe
67
72
  /// to free.
68
73
 
74
+ /// This is easy with a command line utility, but complex in a multithreaded
75
+ /// application. Unless you *really* know what you're doing, fully understand
76
+ /// threads and C memory management, you should probably disable object pools
77
+ /// when creating a long-running GUI application. (I disable them in
78
+ /// MultiMarkdown Composer, for example.)
79
+
69
80
  #ifdef kUseObjectPool
70
81
  void token_pool_init(void); //!< Initialize object pool for allocating tokens
71
82
  void token_pool_drain(void); //!< Drain pool to free memory when parse complete
@@ -85,13 +96,16 @@ struct token {
85
96
  size_t start; //!< Starting offset in the source string
86
97
  size_t len; //!< Length of the token in the source string
87
98
 
88
- struct token * next; //!< Pointer to next token in the chain
89
- struct token * prev; //!< Pointer to previous marker in the chain
90
- struct token * child; //!< Pointer to child chain
99
+ size_t out_start;
100
+ size_t out_len;
101
+
102
+ struct token * next; //!< Pointer to next token in the chain
103
+ struct token * prev; //!< Pointer to previous marker in the chain
104
+ struct token * child; //!< Pointer to child chain
91
105
 
92
- struct token * tail; //!< Pointer to last token in the chain
106
+ struct token * tail; //!< Pointer to last token in the chain
93
107
 
94
- struct token * mate; //!< Pointer to other token in matched pair
108
+ struct token * mate; //!< Pointer to other token in matched pair
95
109
  };
96
110
 
97
111
  typedef struct token token;
@@ -217,11 +231,11 @@ void token_trim_whitespace(token * t, const char * string);
217
231
 
218
232
 
219
233
  ///
220
- token * token_chain_accept(token ** t, short type);
234
+ token * token_chain_accept(token ** t, unsigned short type);
221
235
 
222
236
  token * token_chain_accept_multiple(token ** t, int n, ...);
223
237
 
224
- void token_skip_until_type(token ** t, short type);
238
+ void token_skip_until_type(token ** t, unsigned short type);
225
239
 
226
240
  void token_skip_until_type_multiple(token ** t, int n, ...);
227
241
 
@@ -213,9 +213,6 @@ close:
213
213
  opener_count[peek->type]--;
214
214
  }
215
215
 
216
- #ifndef NDEBUG
217
- fprintf(stderr, "stack now sized %lu\n", s->size);
218
- #endif
219
216
  // Prune matched section
220
217
 
221
218
  if (e->should_prune[pair_type]) {
@@ -230,12 +227,6 @@ close:
230
227
  break;
231
228
  }
232
229
 
233
- #ifndef NDEBUG
234
- else {
235
- fprintf(stderr, "token type %d failed to match stack element\n", walker->type);
236
- }
237
-
238
- #endif
239
230
  i--;
240
231
  }
241
232
  }
@@ -246,18 +237,11 @@ open:
246
237
  if (walker->can_open && e->can_open_pair[walker->type] && walker->unmatched) {
247
238
  stack_push(s, walker);
248
239
  opener_count[walker->type]++;
249
- #ifndef NDEBUG
250
- fprintf(stderr, "push token type %d to stack (%lu elements)\n", walker->type, s->size);
251
- #endif
252
240
  }
253
241
 
254
242
  walker = walker->next;
255
243
  }
256
244
 
257
- #ifndef NDEBUG
258
- fprintf(stderr, "token stack has %lu elements (of %lu)\n", s->size, s->capacity);
259
- #endif
260
-
261
245
  // Remove unused tokens from stack and return to parent
262
246
  s->size = start_counter;
263
247
  }
data/ext/mmd/transclude.c CHANGED
@@ -122,7 +122,7 @@ void mmd_transclude_source(DString * source, const char * search_path, const cha
122
122
  // Make sure we use a parse tree for children
123
123
  stack * parse_stack = parsed;
124
124
 
125
- if (parsed == NULL) {
125
+ if (parse_stack == NULL) {
126
126
  // Create temporary stack
127
127
  parse_stack = stack_new(0);
128
128
  }
@@ -172,12 +172,14 @@ void mmd_transclude_source(DString * source, const char * search_path, const cha
172
172
 
173
173
  // Adjust file wildcard extension for output format
174
174
  // e.g. `foo.*`
175
- if ((format != FORMAT_MMD) && strncmp(&text[stop - start - 4], ".*", 2) == 0) {
175
+ if ((stop - start > 3) && (format != FORMAT_MMD) && strncmp(&text[stop - start - 4], ".*", 2) == 0) {
176
176
  // Trim '.*'
177
177
  d_string_erase(file_path, file_path->currentStringLength - 2, 2);
178
178
 
179
179
  switch (format) {
180
180
  case FORMAT_HTML:
181
+ case FORMAT_HTML_WITH_ASSETS:
182
+ case FORMAT_EPUB:
181
183
  d_string_append(file_path, ".html");
182
184
  break;
183
185
 
@@ -188,6 +190,8 @@ void mmd_transclude_source(DString * source, const char * search_path, const cha
188
190
  break;
189
191
 
190
192
  case FORMAT_FODT:
193
+ case FORMAT_ODT:
194
+ // `.fodt` is the extension for historical reasons
191
195
  d_string_append(file_path, ".fodt");
192
196
  break;
193
197