rmultimarkdown 6.2.2.1 → 6.4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Makefile +2 -2
  3. data/ext/mmd/aho-corasick.c +12 -8
  4. data/ext/mmd/beamer.c +29 -0
  5. data/ext/mmd/critic_markup.c +100 -4
  6. data/ext/mmd/critic_markup.h +7 -0
  7. data/ext/mmd/d_string.c +502 -119
  8. data/ext/mmd/epub.c +2 -4
  9. data/ext/mmd/file.c +436 -0
  10. data/ext/mmd/file.h +153 -0
  11. data/ext/mmd/html.c +130 -37
  12. data/ext/mmd/include/d_string.h +20 -19
  13. data/ext/mmd/include/libMultiMarkdown.h +42 -27
  14. data/ext/mmd/include/token.h +15 -15
  15. data/ext/mmd/latex.c +107 -30
  16. data/ext/mmd/lexer.c +19 -7
  17. data/ext/mmd/lexer.h +2 -2
  18. data/ext/mmd/memoir.c +29 -0
  19. data/ext/mmd/mmd.c +65 -39
  20. data/ext/mmd/object_pool.h +4 -4
  21. data/ext/mmd/opendocument-content.c +95 -13
  22. data/ext/mmd/opendocument.c +315 -313
  23. data/ext/mmd/opml-lexer.c +2183 -0
  24. data/ext/mmd/opml-lexer.h +157 -0
  25. data/ext/mmd/opml-parser.c +1193 -0
  26. data/ext/mmd/opml-parser.h +15 -0
  27. data/ext/mmd/opml-reader.c +435 -0
  28. data/ext/mmd/opml-reader.h +111 -0
  29. data/ext/mmd/opml.c +511 -0
  30. data/ext/mmd/opml.h +115 -0
  31. data/ext/mmd/parser.c +2 -0
  32. data/ext/mmd/rng.c +1 -1
  33. data/ext/mmd/scanners.c +51663 -24824
  34. data/ext/mmd/stack.c +4 -2
  35. data/ext/mmd/stack.h +8 -8
  36. data/ext/mmd/textbundle.c +2 -4
  37. data/ext/mmd/token.c +24 -12
  38. data/ext/mmd/token_pairs.c +2 -2
  39. data/ext/mmd/token_pairs.h +10 -10
  40. data/ext/mmd/transclude.c +1 -226
  41. data/ext/mmd/transclude.h +0 -8
  42. data/ext/mmd/uuid.c +3 -3
  43. data/ext/mmd/version.h +3 -3
  44. data/ext/mmd/writer.c +99 -30
  45. data/ext/mmd/writer.h +11 -0
  46. data/lib/multi_markdown.bundle +0 -0
  47. data/lib/multi_markdown/version.rb +1 -1
  48. metadata +13 -5
  49. data/ext/mmd/fodt.c +0 -2288
  50. data/ext/mmd/fodt.h +0 -81
@@ -0,0 +1,511 @@
1
+ /**
2
+
3
+ MultiMarkdown -- Lightweight markup processor to produce HTML, LaTeX, and more.
4
+
5
+ @file opml.c
6
+
7
+ @brief Export to OPML (Outline Processor Markup Language)
8
+
9
+
10
+ @author Fletcher T. Penney
11
+ @bug
12
+
13
+ **/
14
+
15
+ /*
16
+
17
+ Copyright © 2016 - 2018 Fletcher T. Penney.
18
+
19
+
20
+ The `MultiMarkdown 6` project is released under the MIT License..
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
30
+ text of the license.
31
+
32
+ uthash library:
33
+ Copyright (c) 2005-2016, Troy D. Hanson
34
+
35
+ Licensed under Revised BSD license
36
+
37
+ miniz library:
38
+ Copyright 2013-2014 RAD Game Tools and Valve Software
39
+ Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
40
+
41
+ Licensed under the MIT license
42
+
43
+ argtable3 library:
44
+ Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann
45
+ <sheitmann@users.sourceforge.net>
46
+ All rights reserved.
47
+
48
+ Licensed under the Revised BSD License
49
+
50
+
51
+ ## The MIT License ##
52
+
53
+ Permission is hereby granted, free of charge, to any person obtaining
54
+ a copy of this software and associated documentation files (the
55
+ "Software"), to deal in the Software without restriction, including
56
+ without limitation the rights to use, copy, modify, merge, publish,
57
+ distribute, sublicense, and/or sell copies of the Software, and to
58
+ permit persons to whom the Software is furnished to do so, subject to
59
+ the following conditions:
60
+
61
+ The above copyright notice and this permission notice shall be
62
+ included in all copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
65
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
66
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
67
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
68
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
69
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
70
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
71
+
72
+
73
+ ## Revised BSD License ##
74
+
75
+ Redistribution and use in source and binary forms, with or without
76
+ modification, are permitted provided that the following conditions are
77
+ met:
78
+ * Redistributions of source code must retain the above copyright
79
+ notice, this list of conditions and the following disclaimer.
80
+ * Redistributions in binary form must reproduce the above
81
+ copyright notice, this list of conditions and the following
82
+ disclaimer in the documentation and/or other materials provided
83
+ with the distribution.
84
+ * Neither the name of the <organization> nor the
85
+ names of its contributors may be used to endorse or promote
86
+ products derived from this software without specific prior
87
+ written permission.
88
+
89
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
90
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
91
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
92
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT
93
+ HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
94
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
95
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR
96
+ PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
97
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
98
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100
+
101
+
102
+ */
103
+
104
+ #include <ctype.h>
105
+ #include <stdio.h>
106
+ #include <stdlib.h>
107
+ #include <string.h>
108
+
109
+ #include "opml.h"
110
+ #include "parser.h"
111
+
112
+ #define print(x) d_string_append(out, x)
113
+ #define print_const(x) d_string_append_c_array(out, x, sizeof(x) - 1)
114
+ #define print_char(x) d_string_append_c(out, x)
115
+ #define printf(...) d_string_append_printf(out, __VA_ARGS__)
116
+ #define print_token(t) d_string_append_c_array(out, &(source[t->start]), t->len)
117
+ #define print_localized(x) mmd_print_localized_char_latex(out, x, scratch)
118
+
119
+
120
+
121
+ void mmd_print_source(DString * out, const char * source, size_t start, size_t len) {
122
+ const char * s_start = &source[start];
123
+ const char * s_stop = &source[start + len];
124
+
125
+ char * c = (char *) s_start;
126
+
127
+ while (c < s_stop) {
128
+ switch (*c) {
129
+ case '&':
130
+ print_const("&amp;");
131
+ break;
132
+
133
+ case '<':
134
+ print_const("&lt;");
135
+ break;
136
+
137
+ case '>':
138
+ print_const("&gt;");
139
+ break;
140
+
141
+ case '"':
142
+ print_const("&quot;");
143
+ break;
144
+
145
+ case '\'':
146
+ print_const("&apos;");
147
+ break;
148
+
149
+ case '\n':
150
+ print_const("&#10;");
151
+ break;
152
+
153
+ case '\r':
154
+ print_const("&#13;");
155
+ break;
156
+
157
+ case '\t':
158
+ print_const("&#9;");
159
+ break;
160
+
161
+ default:
162
+ print_char(*c);
163
+ break;
164
+ }
165
+
166
+ c++;
167
+ }
168
+ }
169
+
170
+
171
+ void mmd_check_preamble_opml(DString * out, token * t, scratch_pad * scratch) {
172
+ if (t) {
173
+ token * walker = t->child;
174
+
175
+ while (walker) {
176
+ switch (walker->type) {
177
+ case BLOCK_META:
178
+ walker = walker->next;
179
+ break;
180
+
181
+ case BLOCK_H1:
182
+ case BLOCK_H2:
183
+ case BLOCK_H3:
184
+ case BLOCK_H4:
185
+ case BLOCK_H5:
186
+ case BLOCK_H6:
187
+ case BLOCK_SETEXT_1:
188
+ case BLOCK_SETEXT_2:
189
+ walker = NULL;
190
+ break;
191
+
192
+ default:
193
+ print_const("<outline text=\"(Untitled Preamble)\" _note=\"");
194
+ scratch->opml_item_closed = 0;
195
+ stack_push(scratch->outline_stack, walker);
196
+ walker = NULL;
197
+ break;
198
+ }
199
+ }
200
+ }
201
+ }
202
+
203
+
204
+ /// Export title from metadata
205
+ void mmd_export_title_opml(DString * out, const char * source, scratch_pad * scratch) {
206
+ meta * m;
207
+
208
+ HASH_FIND_STR(scratch->meta_hash, "title", m);
209
+
210
+ if (m) {
211
+ print_const("<head><title>");
212
+
213
+ size_t len = strlen(m->value);
214
+ mmd_print_source(out, m->value, 0, len);
215
+
216
+ print_const("</title></head>\n");
217
+ }
218
+ }
219
+
220
+
221
+ /// Export all metadata
222
+ void mmd_export_metadata_opml(DString * out, const char * source, scratch_pad * scratch) {
223
+ meta * m;
224
+ size_t len;
225
+
226
+ if (scratch->meta_hash) {
227
+ print_const("<outline text=\"Metadata\">\n");
228
+
229
+ for (m = scratch->meta_hash; m != NULL; m = m->hh.next) {
230
+ print_const("<outline text=\"");
231
+ len = strlen(m->key);
232
+ mmd_print_source(out, m->key, 0, len);
233
+
234
+ print_const("\" _note=\"");
235
+ len = strlen(m->value);
236
+ mmd_print_source(out, m->value, 0, len);
237
+
238
+ print_const("\"/>\n");
239
+ }
240
+
241
+ print_const("</outline>\n");
242
+ }
243
+ }
244
+
245
+
246
+ /// Track outline levels to create proper outline structure
247
+ void mmd_outline_add_opml(DString * out, const char * source, token * current, scratch_pad * scratch) {
248
+ token * t;
249
+ short level; // Header level we are adding
250
+ short t_level;
251
+ stack * s = scratch->outline_stack;
252
+
253
+ if (current->type != DOC_START_TOKEN) {
254
+ switch (current->type) {
255
+ case BLOCK_SETEXT_1:
256
+ level = 1;
257
+ break;
258
+
259
+ case BLOCK_SETEXT_2:
260
+ level = 2;
261
+ break;
262
+
263
+ case BLOCK_H1:
264
+ case BLOCK_H2:
265
+ case BLOCK_H3:
266
+ case BLOCK_H4:
267
+ case BLOCK_H5:
268
+ case BLOCK_H6:
269
+ level = 1 + current->type - BLOCK_H1;
270
+ break;
271
+
272
+ default:
273
+ level = 100;
274
+ break;
275
+ }
276
+
277
+ level += scratch->base_header_level - 1;
278
+ } else {
279
+ level = 0;
280
+ }
281
+
282
+ if (s->size) {
283
+ t = stack_peek(s);
284
+
285
+ // Close last outline item?
286
+ if (scratch->opml_item_closed == 0) {
287
+ // Insert direct contents of that item?
288
+ size_t start;
289
+ size_t len;
290
+
291
+ switch (t->type) {
292
+ case BLOCK_SETEXT_1:
293
+ case BLOCK_SETEXT_2:
294
+ if (t->next) {
295
+ start = t->next->start;
296
+ } else {
297
+ start = t->start + t->len;
298
+ }
299
+
300
+ break;
301
+
302
+ case BLOCK_H1:
303
+ case BLOCK_H2:
304
+ case BLOCK_H3:
305
+ case BLOCK_H4:
306
+ case BLOCK_H5:
307
+ case BLOCK_H6:
308
+ start = t->start + t->len;
309
+ break;
310
+
311
+ default:
312
+ start = t->start;
313
+ break;
314
+ }
315
+
316
+ if (current->type != DOC_START_TOKEN) {
317
+ len = current->start - start;
318
+ } else {
319
+ // Finish out document
320
+ len = current->start + current->len - start;
321
+ }
322
+
323
+ // Output as XML string
324
+ mmd_print_source(out, source, start, len);
325
+
326
+ print_const("\">");
327
+ scratch->opml_item_closed = 1;
328
+ }
329
+
330
+ while (t) {
331
+ switch (t->type) {
332
+ case BLOCK_SETEXT_1:
333
+ t_level = 1;
334
+ break;
335
+
336
+ case BLOCK_SETEXT_2:
337
+ t_level = 2;
338
+ break;
339
+
340
+ case BLOCK_H1:
341
+ case BLOCK_H2:
342
+ case BLOCK_H3:
343
+ case BLOCK_H4:
344
+ case BLOCK_H5:
345
+ case BLOCK_H6:
346
+ t_level = 1 + t->type - BLOCK_H1;
347
+ break;
348
+
349
+ default:
350
+ t_level = 100;
351
+ break;
352
+ }
353
+
354
+ t_level += scratch->base_header_level - 1;
355
+
356
+ if (t_level >= level) {
357
+ // Close out level
358
+ print_const("</outline>\n");
359
+
360
+ stack_pop(s);
361
+ t = stack_peek(s);
362
+ } else {
363
+ // Nothing to close
364
+ t = NULL;
365
+ }
366
+ }
367
+ }
368
+
369
+
370
+ // Add current level to stack and open
371
+ if (current->type != DOC_START_TOKEN) {
372
+ stack_push(s, current);
373
+ print_const("<outline");
374
+ scratch->opml_item_closed = 0;
375
+ }
376
+ }
377
+
378
+
379
+ /// Extract header title
380
+ void mmd_export_header_opml(DString * out, const char * source, token * t, scratch_pad * scratch) {
381
+ if (t && t->child) {
382
+ size_t start = t->start;
383
+ size_t stop = t->start + t->len;
384
+
385
+ token * walker = t->child;
386
+
387
+ while (walker) {
388
+ switch (walker->type) {
389
+ case MARKER_H1:
390
+ case MARKER_H2:
391
+ case MARKER_H3:
392
+ case MARKER_H4:
393
+ case MARKER_H5:
394
+ case MARKER_H6:
395
+ walker = walker->next;
396
+ break;
397
+
398
+ default:
399
+ start = walker->start;
400
+ walker = NULL;
401
+ break;
402
+ }
403
+ }
404
+
405
+ walker = t->child->tail;
406
+
407
+ while (walker) {
408
+ switch (walker->type) {
409
+ case TEXT_NL:
410
+ case TEXT_NL_SP:
411
+ case INDENT_TAB:
412
+ case INDENT_SPACE:
413
+ case NON_INDENT_SPACE:
414
+ case MARKER_H1:
415
+ case MARKER_H2:
416
+ case MARKER_H3:
417
+ case MARKER_H4:
418
+ case MARKER_H5:
419
+ case MARKER_H6:
420
+ walker = walker->prev;
421
+ break;
422
+
423
+ default:
424
+ stop = walker->start + walker->len;
425
+ walker = NULL;
426
+ break;
427
+ }
428
+ }
429
+
430
+ mmd_print_source(out, source, start, stop - start);
431
+ }
432
+ }
433
+
434
+
435
+ void mmd_export_token_opml(DString * out, const char * source, token * t, scratch_pad * scratch) {
436
+ if (t == NULL) {
437
+ return;
438
+ }
439
+
440
+ short temp_short;
441
+ char * temp_char = NULL;
442
+ token * temp_token = NULL;
443
+
444
+ switch (t->type) {
445
+ case DOC_START_TOKEN:
446
+ print_const("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<opml version=\"1.0\">\n");
447
+
448
+ // Export metadata
449
+ mmd_export_title_opml(out, source, scratch);
450
+
451
+ print_const("<body>\n");
452
+
453
+ // Check for content before first header
454
+ mmd_check_preamble_opml(out, t, scratch);
455
+
456
+ // Export body
457
+ mmd_export_token_tree_opml(out, source, t->child, scratch);
458
+
459
+ // Close out any existing outline levels
460
+ mmd_outline_add_opml(out, source, t, scratch);
461
+
462
+ mmd_export_metadata_opml(out, source, scratch);
463
+
464
+ print_const("</body>\n</opml>\n");
465
+
466
+ break;
467
+
468
+ case BLOCK_H1:
469
+ case BLOCK_H2:
470
+ case BLOCK_H3:
471
+ case BLOCK_H4:
472
+ case BLOCK_H5:
473
+ case BLOCK_H6:
474
+ case BLOCK_SETEXT_1:
475
+ case BLOCK_SETEXT_2:
476
+ mmd_outline_add_opml(out, source, t, scratch);
477
+
478
+ print_const(" text=\"");
479
+ mmd_export_header_opml(out, source, t, scratch);
480
+ trim_trailing_whitespace_d_string(out);
481
+ print_const("\" _note=\"");
482
+ break;
483
+
484
+ default:
485
+ // Skip everything else
486
+ break;
487
+ }
488
+ }
489
+
490
+
491
+ void mmd_export_token_tree_opml(DString * out, const char * source, token * t, scratch_pad * scratch) {
492
+
493
+ // Prevent stack overflow with "dangerous" input causing extreme recursion
494
+ if (scratch->recurse_depth == kMaxExportRecursiveDepth) {
495
+ return;
496
+ }
497
+
498
+ scratch->recurse_depth++;
499
+
500
+ while (t != NULL) {
501
+ if (scratch->skip_token) {
502
+ scratch->skip_token--;
503
+ } else {
504
+ mmd_export_token_opml(out, source, t, scratch);
505
+ }
506
+
507
+ t = t->next;
508
+ }
509
+
510
+ scratch->recurse_depth--;
511
+ }