rmultimarkdown 4.6.0.2 → 4.7.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MultiMarkdown-4/GLibFacade.c +16 -0
- data/MultiMarkdown-4/GLibFacade.h +1 -0
- data/MultiMarkdown-4/beamer.c +3 -2
- data/MultiMarkdown-4/critic.c +1 -1
- data/MultiMarkdown-4/html.c +6 -1
- data/MultiMarkdown-4/latex.c +4 -1
- data/MultiMarkdown-4/libMultiMarkdown.h +3 -1
- data/MultiMarkdown-4/lyx.c +3 -0
- data/MultiMarkdown-4/memoir.c +1 -1
- data/MultiMarkdown-4/multimarkdown.c +59 -13
- data/MultiMarkdown-4/odf.c +4 -1
- data/MultiMarkdown-4/opml.c +1 -1
- data/MultiMarkdown-4/parse_utilities.c +10 -2
- data/MultiMarkdown-4/parser.c +7070 -6682
- data/MultiMarkdown-4/parser.h +4 -2
- data/MultiMarkdown-4/rtf.c +14 -0
- data/MultiMarkdown-4/text.c +1 -1
- data/MultiMarkdown-4/toc.c +142 -0
- data/MultiMarkdown-4/toc.h +15 -0
- data/MultiMarkdown-4/transclude.c +78 -5
- data/MultiMarkdown-4/transclude.h +3 -2
- data/MultiMarkdown-4/writer.c +19 -5
- data/MultiMarkdown-4/writer.h +1 -0
- data/lib/multi_markdown.bundle +0 -0
- data/lib/multi_markdown/version.rb +1 -1
- metadata +36 -34
data/MultiMarkdown-4/parser.h
CHANGED
@@ -14,10 +14,10 @@
|
|
14
14
|
|
15
15
|
#define TABSTOP 4
|
16
16
|
|
17
|
-
#define MMD_VERSION "4.
|
17
|
+
#define MMD_VERSION "4.7"
|
18
18
|
|
19
19
|
#define MMD_COPYRIGHT \
|
20
|
-
"Copyright (c) 2013-
|
20
|
+
"Copyright (c) 2013-2015 Fletcher T. Penney.\n\n" \
|
21
21
|
"LyX export code (c) 2013-2014 Charles R. Cowan,\n" \
|
22
22
|
"licensed under both GPL and MIT licenses.\n\n" \
|
23
23
|
"portions based on peg-markdown - Copyright (c) 2008-2009 John MacFarlane.\n" \
|
@@ -71,6 +71,7 @@ typedef struct {
|
|
71
71
|
int odf_para_type; /* what type of paragraph do we need? */
|
72
72
|
bool odf_list_needs_end_p; /* is there a <p> that need to be closed */
|
73
73
|
int random_seed_base; /* Allow random footnotes */
|
74
|
+
int toc_level; /* Track depth for TOC */
|
74
75
|
int table_row; /* CRC - Track the current row number */
|
75
76
|
int lyx_para_type; /* CRC - the type of paragraph being processed */
|
76
77
|
int lyx_level; /* CRC - nesting level */
|
@@ -180,5 +181,6 @@ int tree_contains_key_count(node *list, int key);
|
|
180
181
|
bool check_timeout();
|
181
182
|
|
182
183
|
void debug_node(node *n);
|
184
|
+
void debug_node_tree(node *n);
|
183
185
|
|
184
186
|
#endif
|
data/MultiMarkdown-4/rtf.c
CHANGED
@@ -474,6 +474,20 @@ void print_rtf_node(GString *out, node *n, scratch_pad *scratch) {
|
|
474
474
|
free(temp);
|
475
475
|
}
|
476
476
|
break;
|
477
|
+
case HTMLBLOCK:
|
478
|
+
/* don't print HTML block */
|
479
|
+
/* but do print HTML comments for raw RTF */
|
480
|
+
if (strncmp(n->str,"<!--",4) == 0) {
|
481
|
+
pad(out, 2, scratch);
|
482
|
+
/* trim "-->" from end */
|
483
|
+
n->str[strlen(n->str)-3] = '\0';
|
484
|
+
g_string_append_printf(out, "%s", &n->str[4]);
|
485
|
+
scratch->padded = 0;
|
486
|
+
}
|
487
|
+
break;
|
488
|
+
case TOC:
|
489
|
+
print_rtf_node_tree(out,n->children, scratch);
|
490
|
+
break;
|
477
491
|
default:
|
478
492
|
fprintf(stderr, "print_rtf_node encountered unknown node key = %d\n",n->key);
|
479
493
|
g_string_append_printf(out, "%s",n->str);
|
data/MultiMarkdown-4/text.c
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
test.c -- plain text writer function as an example.
|
4
4
|
Recreates the input source.
|
5
5
|
|
6
|
-
(c) 2013 Fletcher T. Penney (http://fletcherpenney.net/).
|
6
|
+
(c) 2013-2015 Fletcher T. Penney (http://fletcherpenney.net/).
|
7
7
|
|
8
8
|
This program is free software; you can redistribute it and/or modify
|
9
9
|
it under the terms of the GNU General Public License or the MIT
|
@@ -0,0 +1,142 @@
|
|
1
|
+
/*
|
2
|
+
|
3
|
+
toc.c -- Table of contents
|
4
|
+
|
5
|
+
(c) 2013-2015 Fletcher T. Penney (http://fletcherpenney.net/).
|
6
|
+
|
7
|
+
This program is free software; you can redistribute it and/or modify
|
8
|
+
it under the terms of the GNU General Public License or the MIT
|
9
|
+
license. See LICENSE for details.
|
10
|
+
|
11
|
+
This program is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU General Public License for more details.
|
15
|
+
|
16
|
+
*/
|
17
|
+
|
18
|
+
#include "toc.h"
|
19
|
+
|
20
|
+
|
21
|
+
/* print_toc_node_tree -- convert node tree to LaTeX */
|
22
|
+
void print_toc_node_tree(GString *out, node *list, scratch_pad *scratch) {
|
23
|
+
#ifdef DEBUG_ON
|
24
|
+
fprintf(stderr, "print_toc_node_tree\n");
|
25
|
+
#endif
|
26
|
+
int lev;
|
27
|
+
while (list != NULL) {
|
28
|
+
if (list->key == HEADINGSECTION) {
|
29
|
+
lev = list->children->key;
|
30
|
+
|
31
|
+
print_toc_section_and_children(out, list, scratch);
|
32
|
+
|
33
|
+
while ((list->next != NULL) && (list->next->key == HEADINGSECTION)
|
34
|
+
&& (list->next->children->key > lev)) {
|
35
|
+
list = list->next;
|
36
|
+
}
|
37
|
+
} else {
|
38
|
+
print_toc_node(out, list, scratch);
|
39
|
+
}
|
40
|
+
list = list->next;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
/* print_toc_section_and_children -- we want to stay inside the outline structure */
|
45
|
+
void print_toc_section_and_children(GString *out, node *list, scratch_pad *scratch) {
|
46
|
+
#ifdef DEBUG_ON
|
47
|
+
fprintf(stderr, "print_toc_section_and_children: %d\n",list->key);
|
48
|
+
#endif
|
49
|
+
int lev = list->children->key;
|
50
|
+
|
51
|
+
/* print current section (parent) */
|
52
|
+
print_toc_node(out, list, scratch);
|
53
|
+
|
54
|
+
scratch->toc_level ++;
|
55
|
+
|
56
|
+
/* check for child nodes */
|
57
|
+
while ((list->next != NULL) && (list->next->key == HEADINGSECTION) && (list->next->children->key > lev)) {
|
58
|
+
/* next item is also a HEADINGSECTION and is a child */
|
59
|
+
if (list->next->children->key - lev == 1)
|
60
|
+
print_toc_section_and_children(out, list->next, scratch);
|
61
|
+
list = list->next;
|
62
|
+
}
|
63
|
+
|
64
|
+
scratch->toc_level --;
|
65
|
+
}
|
66
|
+
|
67
|
+
/* print_toc_node -- convert given node to OPML and append */
|
68
|
+
void print_toc_node(GString *out, node *n, scratch_pad *scratch) {
|
69
|
+
char *temp;
|
70
|
+
int i;
|
71
|
+
|
72
|
+
#ifdef DEBUG_ON
|
73
|
+
fprintf(stderr, "print_toc_node: %d\n",n->key);
|
74
|
+
#endif
|
75
|
+
switch (n->key) {
|
76
|
+
case HEADINGSECTION:
|
77
|
+
/* Need to handle "nesting" properly */
|
78
|
+
for (i = 0; i < scratch->toc_level; ++i)
|
79
|
+
{
|
80
|
+
g_string_append_printf(out, "\t");
|
81
|
+
}
|
82
|
+
g_string_append_printf(out, "* ");
|
83
|
+
|
84
|
+
/* Print header */
|
85
|
+
print_toc_node(out, n->children, scratch);
|
86
|
+
|
87
|
+
break;
|
88
|
+
case H1: case H2: case H3: case H4: case H5: case H6:
|
89
|
+
if ((n->children != NULL) && (n->children->key == AUTOLABEL)) {
|
90
|
+
temp = label_from_string(n->children->str);
|
91
|
+
/* use label for header since one was specified (MMD)*/
|
92
|
+
g_string_append_printf(out, "[");
|
93
|
+
print_toc_node_tree(out, n->children, scratch);
|
94
|
+
g_string_append_printf(out, "][%s]\n", temp);
|
95
|
+
} else {
|
96
|
+
temp = label_from_node_tree(n->children);
|
97
|
+
g_string_append_printf(out, "[");
|
98
|
+
print_toc_node_tree(out, n->children, scratch);
|
99
|
+
g_string_append_printf(out, "][%s]\n", temp);
|
100
|
+
}
|
101
|
+
free(temp);
|
102
|
+
break;
|
103
|
+
case STR:
|
104
|
+
print_toc_string(out, n->str);
|
105
|
+
break;
|
106
|
+
case SPACE:
|
107
|
+
g_string_append_printf(out, "%s", n->str);
|
108
|
+
break;
|
109
|
+
case LINK:
|
110
|
+
print_toc_node_tree(out, n->children, scratch);
|
111
|
+
break;
|
112
|
+
case LINKREFERENCE:
|
113
|
+
break;
|
114
|
+
case AUTOLABEL:
|
115
|
+
break;
|
116
|
+
case LIST:
|
117
|
+
print_toc_node_tree(out, n->children, scratch);
|
118
|
+
break;
|
119
|
+
default: fprintf(stderr, "print_html_node encountered unknown node key = %d\n",n->key);
|
120
|
+
break;
|
121
|
+
}
|
122
|
+
#ifdef DEBUG_ON
|
123
|
+
fprintf(stderr, "finish print_toc_node: %d\n", n->key);
|
124
|
+
#endif
|
125
|
+
}
|
126
|
+
|
127
|
+
/* print_toc_string - print string, escaping for OPML */
|
128
|
+
void print_toc_string(GString *out, char *str) {
|
129
|
+
while (*str != '\0') {
|
130
|
+
switch (*str) {
|
131
|
+
case '[':
|
132
|
+
g_string_append_printf(out, "\\[");
|
133
|
+
break;
|
134
|
+
case ']':
|
135
|
+
g_string_append_printf(out, "\\]");
|
136
|
+
break;
|
137
|
+
default:
|
138
|
+
g_string_append_c(out, *str);
|
139
|
+
}
|
140
|
+
str++;
|
141
|
+
}
|
142
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef TOC_PARSER_H
|
2
|
+
#define TOC_PARSER_H
|
3
|
+
|
4
|
+
#include "parser.h"
|
5
|
+
#include "writer.h"
|
6
|
+
|
7
|
+
void begin_toc_output(GString *out, node* list, scratch_pad *scratch);
|
8
|
+
void print_toc_node_tree(GString *out, node *list, scratch_pad *scratch);
|
9
|
+
void print_toc_node(GString *out, node *n, scratch_pad *scratch);
|
10
|
+
void print_toc_section_and_children(GString *out, node *list, scratch_pad *scratch);
|
11
|
+
void end_toc_output(GString *out, node* list, scratch_pad *scratch);
|
12
|
+
void print_toc_string(GString *out, char *str);
|
13
|
+
|
14
|
+
|
15
|
+
#endif
|
@@ -17,6 +17,9 @@
|
|
17
17
|
|
18
18
|
#include "transclude.h"
|
19
19
|
#include "parser.h"
|
20
|
+
#if defined(__WIN32)
|
21
|
+
#include <windows.h>
|
22
|
+
#endif
|
20
23
|
|
21
24
|
|
22
25
|
/* Combine directory and filename to create a full path */
|
@@ -48,19 +51,43 @@ char * path_from_dir_base(char *dir, char *base) {
|
|
48
51
|
return result;
|
49
52
|
}
|
50
53
|
|
54
|
+
/* Separate filename and directory from a full path */
|
55
|
+
/* See http://stackoverflow.com/questions/1575278/function-to-split-a-filepath-into-path-and-file */
|
56
|
+
void split_path_file(char** dir, char** file, char *path) {
|
57
|
+
char *slash = path, *next;
|
58
|
+
#if defined(__WIN32)
|
59
|
+
const char sep[] = "\\";
|
60
|
+
#else
|
61
|
+
const char sep[] = "/";
|
62
|
+
#endif
|
63
|
+
|
64
|
+
while ((next = strpbrk(slash + 1, sep))) slash = next;
|
65
|
+
if (path != slash) slash++;
|
66
|
+
*dir = strndup(path, slash - path);
|
67
|
+
*file = strdup(slash);
|
68
|
+
}
|
69
|
+
|
51
70
|
/* Return pointer to beginning of text without metadata */
|
71
|
+
/* NOTE: This is not a new string, and does not need to be freed separately */
|
52
72
|
char * source_without_metadata(char * source, unsigned long extensions ) {
|
53
73
|
char *result;
|
54
74
|
|
55
75
|
if (has_metadata(source, extensions)) {
|
56
76
|
/* If we have metadata, then return just the body */
|
77
|
+
/* TODO: This could miss YAML Metadata that does not contain
|
78
|
+
blank line afterwards */
|
57
79
|
result = strstr(source, "\n\n");
|
58
80
|
|
59
81
|
if (result != NULL)
|
60
|
-
return result+2;
|
82
|
+
return result + 2;
|
61
83
|
}
|
62
84
|
|
63
85
|
/* No metadata, so return original pointer */
|
86
|
+
|
87
|
+
/* But check for UTF-8 BOM and skip if present */
|
88
|
+
if (strncmp(source, "\xef\xbb\xbf",3) == 0)
|
89
|
+
return source + 3;
|
90
|
+
|
64
91
|
return source;
|
65
92
|
}
|
66
93
|
|
@@ -70,7 +97,7 @@ char * source_without_metadata(char * source, unsigned long extensions ) {
|
|
70
97
|
Pass the path to the current folder if available -- should be a full path.
|
71
98
|
|
72
99
|
Keep track of what we're parsing to prevent recursion using stack. */
|
73
|
-
void transclude_source(GString *source, char *basedir, char *stack, int output_format) {
|
100
|
+
void transclude_source(GString *source, char *basedir, char *stack, int output_format, GString *manifest) {
|
74
101
|
char *base = NULL;
|
75
102
|
char *path = NULL;
|
76
103
|
char *start;
|
@@ -165,6 +192,18 @@ void transclude_source(GString *source, char *basedir, char *stack, int output_f
|
|
165
192
|
|
166
193
|
pos = stop - source->str;
|
167
194
|
|
195
|
+
/* Add to the manifest (if not already included) */
|
196
|
+
if (manifest != NULL) {
|
197
|
+
temp = strstr(manifest->str,filename->str);
|
198
|
+
|
199
|
+
if ((temp != NULL) && (temp[strlen(filename->str)] == '\n')){
|
200
|
+
/* Already on manifest */
|
201
|
+
} else {
|
202
|
+
g_string_append_printf(manifest,"%s\n",filename->str);
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
|
168
207
|
/* Don't reparse ourselves */
|
169
208
|
if (stack != NULL) {
|
170
209
|
temp = strstr(stack,filename->str);
|
@@ -177,7 +216,15 @@ void transclude_source(GString *source, char *basedir, char *stack, int output_f
|
|
177
216
|
}
|
178
217
|
|
179
218
|
/* Read file */
|
219
|
+
#if defined(__WIN32)
|
220
|
+
int wchars_num = MultiByteToWideChar(CP_UTF8, 0, filename->str, -1, NULL, 0);
|
221
|
+
wchar_t wstr[wchars_num];
|
222
|
+
MultiByteToWideChar(CP_UTF8, 0, filename->str, -1, wstr, wchars_num);
|
223
|
+
|
224
|
+
if ((input = _wfopen(wstr, L"r")) != NULL ) {
|
225
|
+
#else
|
180
226
|
if ((input = fopen(filename->str, "r")) != NULL ) {
|
227
|
+
#endif
|
181
228
|
filebuffer = g_string_new("");
|
182
229
|
|
183
230
|
while ((curchar = fgetc(input)) != EOF)
|
@@ -195,8 +242,18 @@ void transclude_source(GString *source, char *basedir, char *stack, int output_f
|
|
195
242
|
|
196
243
|
|
197
244
|
/* Recursively transclude files */
|
198
|
-
transclude_source(filebuffer, folder->str, stackstring->str, output_format);
|
199
245
|
|
246
|
+
/* We want to reset the base directory if we enter a subdirectory */
|
247
|
+
char * new_dir;
|
248
|
+
char * file_only;
|
249
|
+
split_path_file(&new_dir, &file_only, filename->str);
|
250
|
+
|
251
|
+
/* transclude_source(filebuffer, folder->str, stackstring->str, output_format, manifest); */
|
252
|
+
transclude_source(filebuffer, new_dir, stackstring->str, output_format, manifest);
|
253
|
+
|
254
|
+
free(new_dir);
|
255
|
+
free(file_only);
|
256
|
+
|
200
257
|
temp = source_without_metadata(filebuffer->str, 0x000000);
|
201
258
|
|
202
259
|
g_string_insert(source, pos, temp);
|
@@ -224,11 +281,27 @@ void transclude_source(GString *source, char *basedir, char *stack, int output_f
|
|
224
281
|
/* Allow for a footer to specify files to be appended to the end of the text, and then transcluded.
|
225
282
|
Useful for appending a list of footnotes, citations, abbreviations, etc. to each separate file,
|
226
283
|
but not including multiple copies when processing the master file. */
|
227
|
-
void
|
284
|
+
void append_mmd_footer(GString *source) {
|
228
285
|
/* Look for mmd_footer metadata */
|
229
286
|
if (has_metadata(source->str, 0x000000)) {
|
230
287
|
char *meta = extract_metadata_value(source->str, 0x000000, "mmdfooter");
|
231
288
|
if (meta != NULL)
|
232
|
-
g_string_append_printf(source, "\n\n{{%s}}\n",meta);
|
289
|
+
g_string_append_printf(source, "\n\n{{%s}}\n", meta);
|
290
|
+
}
|
291
|
+
}
|
292
|
+
|
293
|
+
void prepend_mmd_header(GString *source) {
|
294
|
+
/* Same thing, but to be inserted after metadata and before content */
|
295
|
+
if (has_metadata(source->str, 0x000000)) {
|
296
|
+
char *meta = extract_metadata_value(source->str, 0x000000, "mmdheader");
|
297
|
+
if (meta != NULL) {
|
298
|
+
char *content = strstr(source->str, "\n\n");
|
299
|
+
if (content != NULL) {
|
300
|
+
size_t pos = content - source->str;
|
301
|
+
g_string_insert_printf(source, pos, "\n\n{{%s}}", meta);
|
302
|
+
} else {
|
303
|
+
g_string_append_printf(source, "\n\n{{%s}}\n", meta);
|
304
|
+
}
|
305
|
+
}
|
233
306
|
}
|
234
307
|
}
|
@@ -23,5 +23,6 @@
|
|
23
23
|
#include "GLibFacade.h"
|
24
24
|
|
25
25
|
char * source_without_metadata(char * source, unsigned long extensions);
|
26
|
-
void transclude_source(GString *source, char *basedir, char *stack, int format);
|
27
|
-
void
|
26
|
+
void transclude_source(GString *source, char *basedir, char *stack, int format, GString *manifest);
|
27
|
+
void append_mmd_footer(GString *source);
|
28
|
+
void prepend_mmd_header(GString *source);
|
data/MultiMarkdown-4/writer.c
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
writer.c -- General routines for converting parse structure to various
|
4
4
|
output formats.
|
5
5
|
|
6
|
-
(c) 2013 Fletcher T. Penney (http://fletcherpenney.net/).
|
6
|
+
(c) 2013-2015 Fletcher T. Penney (http://fletcherpenney.net/).
|
7
7
|
|
8
8
|
Derived from peg-multimarkdown, which was forked from peg-markdown,
|
9
9
|
which is (c) 2008 John MacFarlane (jgm at berkeley dot edu), and
|
@@ -41,13 +41,13 @@ char * export_node_tree(node *list, int format, unsigned long extensions) {
|
|
41
41
|
(format != CRITIC_ACCEPT_FORMAT) &&
|
42
42
|
(format != CRITIC_REJECT_FORMAT) &&
|
43
43
|
(format != CRITIC_HTML_HIGHLIGHT_FORMAT)) {
|
44
|
-
/* Parse for link, images, etc reference definitions */
|
45
|
-
extract_references(list, scratch);
|
46
|
-
|
47
44
|
/* Find defined abbreviations */
|
48
45
|
extract_abbreviations(list, scratch);
|
49
46
|
/* Apply those abbreviations to source text */
|
50
47
|
find_abbreviations(list, scratch);
|
48
|
+
|
49
|
+
/* Parse for link, images, etc reference definitions */
|
50
|
+
extract_references(list, scratch);
|
51
51
|
}
|
52
52
|
|
53
53
|
/* Change our desired format based on metadata */
|
@@ -138,6 +138,10 @@ char * export_node_tree(node *list, int format, unsigned long extensions) {
|
|
138
138
|
case CRITIC_HTML_HIGHLIGHT_FORMAT:
|
139
139
|
print_critic_html_highlight_node_tree(out, list, scratch);
|
140
140
|
break;
|
141
|
+
case TOC_FORMAT:
|
142
|
+
scratch->toc_level = 0;
|
143
|
+
print_toc_node_tree(out,list,scratch);
|
144
|
+
break;
|
141
145
|
default:
|
142
146
|
fprintf(stderr, "Unknown export format = %d\n",format);
|
143
147
|
exit(EXIT_FAILURE);
|
@@ -225,6 +229,8 @@ void extract_abbreviations(node *list, scratch_pad *scratch) {
|
|
225
229
|
case HEADINGSECTION:
|
226
230
|
case RAW:
|
227
231
|
case LIST:
|
232
|
+
case BLOCKQUOTEMARKER:
|
233
|
+
case BLOCKQUOTE:
|
228
234
|
extract_abbreviations(list->children, scratch);
|
229
235
|
break;
|
230
236
|
default:
|
@@ -293,11 +299,19 @@ void find_abbreviations(node *list, scratch_pad *scratch) {
|
|
293
299
|
}
|
294
300
|
break;
|
295
301
|
case LIST:
|
302
|
+
case ORDEREDLIST:
|
303
|
+
case BULLETLIST:
|
304
|
+
case LISTITEM:
|
296
305
|
case HEADINGSECTION:
|
297
306
|
case PARA:
|
307
|
+
case PLAIN:
|
298
308
|
case LINK:
|
299
309
|
case LINKREFERENCE:
|
300
310
|
case NOTEREFERENCE:
|
311
|
+
case NOTESOURCE:
|
312
|
+
case GLOSSARYSOURCE:
|
313
|
+
case BLOCKQUOTEMARKER:
|
314
|
+
case BLOCKQUOTE:
|
301
315
|
/* Check children of these elements */
|
302
316
|
find_abbreviations(list->children, scratch);
|
303
317
|
break;
|
@@ -714,4 +728,4 @@ link_data * load_link_data(node *n, scratch_pad *scratch) {
|
|
714
728
|
}
|
715
729
|
|
716
730
|
return r;
|
717
|
-
}
|
731
|
+
}
|