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,15 @@
1
+ #define OPML_XML 1
2
+ #define OPML_WSNL 2
3
+ #define OPML_OPML_OPEN 3
4
+ #define OPML_OPML_CLOSE 4
5
+ #define OPML_HEAD_OPEN 5
6
+ #define OPML_HEAD_CLOSE 6
7
+ #define OPML_TITLE_OPEN 7
8
+ #define OPML_TITLE_CLOSE 8
9
+ #define OPML_BODY_OPEN 9
10
+ #define OPML_BODY_CLOSE 10
11
+ #define OPML_OUTLINE_OPEN 11
12
+ #define OPML_OUTLINE_CLOSE 12
13
+ #define OPML_OUTLINE_PREAMBLE 13
14
+ #define OPML_OUTLINE_METADATA 14
15
+ #define OPML_OUTLINE_SELF_CLOSE 15
@@ -0,0 +1,435 @@
1
+ /**
2
+
3
+ MultiMarkdown -- Lightweight markup processor to produce HTML, LaTeX, and more.
4
+
5
+ @file opml-reader.c
6
+
7
+ @brief
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 <stdio.h>
105
+ #include <stdlib.h>
106
+
107
+ #include "mmd.h"
108
+ #include "opml-reader.h"
109
+ #include "opml-lexer.h"
110
+ #include "opml-parser.h"
111
+ #include "token.h"
112
+
113
+
114
+ // Basic parser function declarations
115
+ void * OPMLAlloc();
116
+ void OPML();
117
+ void OPMLFree();
118
+ void OPMLTrace();
119
+
120
+
121
+ #define print(x) d_string_append(out, x)
122
+ #define print_const(x) d_string_append_c_array(out, x, sizeof(x) - 1)
123
+ #define print_char(x) d_string_append_c(out, x)
124
+ #define printf(...) d_string_append_printf(out, __VA_ARGS__)
125
+
126
+
127
+ /// Create a token chain from source OPML string
128
+ token * tokenize_opml_string(mmd_engine * e, size_t start, size_t len) {
129
+
130
+ // Create a scanner (for re2c)
131
+ Scanner s;
132
+ s.start = &e->dstr->str[start];
133
+ s.cur = s.start;
134
+
135
+ // Where do we stop parsing?
136
+ const char * stop = &e->dstr->str[start] + len;
137
+
138
+ int type; // TOKEN type
139
+ token * t; // Create tokens for incorporation
140
+
141
+ token * root = token_new(0, start, len); // Store the final parse tree here
142
+
143
+ const char * last_stop = &e->dstr->str[start]; // Remember where last token ended
144
+
145
+ do {
146
+ // Scan for next token (type of 0 means there is nothing left);
147
+ type = opml_scan(&s, stop);
148
+
149
+ //if (type && s.start != last_stop) {
150
+ if (s.start != last_stop) {
151
+ // We skipped characters between tokens
152
+
153
+ if (type) {
154
+ // Create a default token type for the skipped characters
155
+ // t = token_new(TEXT_PLAIN, (size_t)(last_stop - e->dstr->str), (size_t)(s.start - last_stop));
156
+ } else {
157
+ if (stop > last_stop) {
158
+ // Source text ends without newline
159
+ // t = token_new(TEXT_PLAIN, (size_t)(last_stop - e->dstr->str), (size_t)(stop - last_stop));
160
+ }
161
+ }
162
+ } else if (type == 0 && stop > last_stop) {
163
+ // Source text ends without newline
164
+ // t = token_new(TEXT_PLAIN, (size_t)(last_stop - e->dstr->str), (size_t)(stop - last_stop));
165
+ }
166
+
167
+
168
+ switch (type) {
169
+ case 0:
170
+ // 0 means we finished with input
171
+ break;
172
+
173
+ case OPML_WSNL:
174
+ // Ignore for now
175
+ break;
176
+
177
+ default:
178
+ t = token_new(type, (size_t)(s.start - e->dstr->str), (size_t)(s.cur - s.start));
179
+ token_chain_append(root, t);
180
+ break;
181
+ }
182
+
183
+ // Remember where token ends to detect skipped characters
184
+ last_stop = s.cur;
185
+ } while (type != 0);
186
+
187
+ return root;
188
+ }
189
+
190
+
191
+ void print_opml_text(DString * out, const char * source, size_t start, size_t len) {
192
+ const char * s_start = &source[start];
193
+ const char * s_stop = &source[start + len];
194
+
195
+ char * c = (char *) s_start;
196
+
197
+ while (c < s_stop) {
198
+ switch (*c) {
199
+ case '&':
200
+ switch (*++c) {
201
+ case '#':
202
+ if (strncmp(c, "#10;", 4) == 0) {
203
+ print_char('\n');
204
+ c += 4;
205
+ continue;
206
+ }
207
+
208
+ if (strncmp(c, "#9;", 3) == 0) {
209
+ print_char('\t');
210
+ c += 3;
211
+ continue;
212
+ }
213
+
214
+ if (strncmp(c, "#13;", 4) == 0) {
215
+ print_char('\r');
216
+ c += 4;
217
+ continue;
218
+ }
219
+
220
+ break;
221
+
222
+ case 'a':
223
+ if (strncmp(c, "amp;", 4) == 0) {
224
+ print_char('&');
225
+ c += 4;
226
+ continue;
227
+ }
228
+
229
+ if (strncmp(c, "apos;", 5) == 0) {
230
+ print_char('\'');
231
+ c += 5;
232
+ continue;
233
+ }
234
+
235
+ break;
236
+
237
+ case 'l':
238
+ if (strncmp(c, "lt;", 3) == 0) {
239
+ print_char('<');
240
+ c += 3;
241
+ continue;
242
+ }
243
+
244
+ break;
245
+
246
+ case 'g':
247
+ if (strncmp(c, "gt;", 3) == 0) {
248
+ print_char('>');
249
+ c += 3;
250
+ continue;
251
+ }
252
+
253
+ break;
254
+
255
+ case 'q':
256
+ if (strncmp(c, "quot;", 5) == 0) {
257
+ print_char('"');
258
+ c += 5;
259
+ continue;
260
+ }
261
+
262
+ break;
263
+
264
+ default:
265
+ break;
266
+ }
267
+
268
+ print_char('&');
269
+ continue;
270
+ break;
271
+
272
+ default:
273
+ print_char(*c);
274
+ break;
275
+ }
276
+
277
+ c++;
278
+ }
279
+ }
280
+
281
+
282
+
283
+ void parse_opml_token_chain(mmd_engine * e, token * chain) {
284
+
285
+ void* pParser = OPMLAlloc (malloc); // Create a parser (for lemon)
286
+ token * walker = chain->next; // Walk the existing tree
287
+ token * remainder; // Hold unparsed tail of chain
288
+
289
+ #ifndef NDEBUG
290
+ OPMLTrace(stderr, "parser >>");
291
+ #endif
292
+
293
+ // Remove existing token tree
294
+ e->root = NULL;
295
+
296
+ while (walker != NULL) {
297
+ remainder = walker->next;
298
+
299
+ OPML(pParser, walker->type, walker, e);
300
+
301
+ walker = remainder;
302
+ }
303
+
304
+ // Signal finish to parser
305
+ #ifndef NDEBUG
306
+ fprintf(stderr, "\nFinish parse\n");
307
+ #endif
308
+ OPML(pParser, 0, NULL, e);
309
+
310
+ if (e->root) {
311
+ // Successful parse -- process to new source document
312
+ DString * final = d_string_new("");
313
+ DString * metadata = d_string_new("");
314
+ DString * out = final;
315
+
316
+ size_t header_level = 0;
317
+ size_t start, len;
318
+
319
+ walker = chain->next;
320
+
321
+ while (walker) {
322
+ switch (walker->type) {
323
+ case OPML_OUTLINE_PREAMBLE:
324
+ case OPML_OUTLINE_OPEN:
325
+ case OPML_OUTLINE_SELF_CLOSE:
326
+ header_level++;
327
+
328
+ // Advance over `<outline`
329
+ start = walker->start + 8;
330
+
331
+ start += scan_text(&(e->dstr->str[start]));
332
+ len = scan_double_quoted(&(e->dstr->str[start]));
333
+
334
+ if (strncmp(&(e->dstr->str[start + 1]), "(Untitled Preamble)", 19) != 0) {
335
+ if (out == metadata) {
336
+ print_opml_text(out, e->dstr->str, start + 1, len - 2);
337
+ print_const(":\t");
338
+ } else {
339
+ // Print header
340
+ if (scan_encoded_newline(&(e->dstr->str[start + 1]), len - 2) == -1) {
341
+ // ATX header
342
+ for (int i = 0; i < header_level; ++i) {
343
+ print_char('#');
344
+ }
345
+
346
+ print_char(' ');
347
+ }
348
+
349
+ print_opml_text(out, e->dstr->str, start + 1, len - 2);
350
+
351
+ if (scan_encoded_newline(&(e->dstr->str[start + 1]), len - 2) == -1) {
352
+ // ATX header
353
+ print_char(' ');
354
+
355
+ for (int i = 0; i < header_level; ++i) {
356
+ print_char('#');
357
+ }
358
+ } else {
359
+ // Print Setext Header
360
+ switch (header_level) {
361
+ case 1:
362
+ print_const("\n======");
363
+ break;
364
+
365
+ default:
366
+ print_const("\n------");
367
+ break;
368
+ }
369
+ }
370
+
371
+ print_const("\n");
372
+ }
373
+ }
374
+
375
+ // Print contents
376
+ start += len;
377
+ start += scan_note(&(e->dstr->str[start]));
378
+ len = scan_double_quoted(&(e->dstr->str[start]));
379
+
380
+ print_opml_text(out, e->dstr->str, start + 1, len - 2);
381
+
382
+ if (out == metadata) {
383
+ print_char('\n');
384
+ }
385
+
386
+ if (walker->type == OPML_OUTLINE_SELF_CLOSE) {
387
+ header_level--;
388
+ }
389
+
390
+ break;
391
+
392
+ case OPML_OUTLINE_METADATA:
393
+ // Now handle metadata
394
+ out = metadata;
395
+ header_level++;
396
+ break;
397
+
398
+ case OPML_OUTLINE_CLOSE:
399
+ header_level--;
400
+ break;
401
+
402
+ default:
403
+ break;
404
+ }
405
+
406
+ walker = walker->next;
407
+ }
408
+
409
+ // Append body to metadata
410
+ d_string_append_c_array(metadata, final->str, final->currentStringLength);
411
+
412
+ // TODO: How to safely swap the new text, given that we might not own e->dstr->str?
413
+
414
+ free(e->dstr->str);
415
+ e->dstr->str = metadata->str;
416
+ e->dstr->currentStringLength = metadata->currentStringLength;
417
+
418
+ d_string_free(metadata, false);
419
+ d_string_free(final, true);
420
+ } else {
421
+ // Unsuccessful parse -- free token chain
422
+ }
423
+
424
+ // Clean up token chain
425
+ token_tree_free(chain);
426
+
427
+ OPMLFree(pParser, free);
428
+ }
429
+
430
+
431
+ /// Create a token chain from source OPML string
432
+ void mmd_convert_opml_string(mmd_engine * e, size_t start, size_t len) {
433
+ token * chain = tokenize_opml_string(e, start, len);
434
+ parse_opml_token_chain(e, chain);
435
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+
3
+ MultiMarkdown -- Lightweight markup processor to produce HTML, LaTeX, and more.
4
+
5
+ @file opml-reader.h
6
+
7
+ @brief
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
+
105
+ #ifndef OPML_READER_MULTIMARKDOWN_H
106
+ #define OPML_READER_MULTIMARKDOWN_H
107
+
108
+ /// Create a token chain from source OPML string
109
+ void mmd_convert_opml_string(mmd_engine * e, size_t start, size_t len);
110
+
111
+ #endif