rmultimarkdown 4.6.0.2 → 4.7.0.1

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.
@@ -14,10 +14,10 @@
14
14
 
15
15
  #define TABSTOP 4
16
16
 
17
- #define MMD_VERSION "4.6"
17
+ #define MMD_VERSION "4.7"
18
18
 
19
19
  #define MMD_COPYRIGHT \
20
- "Copyright (c) 2013-2014 Fletcher T. Penney.\n\n" \
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
@@ -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);
@@ -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 append_mmd_footers(GString *source) {
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 append_mmd_footers(GString *source);
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);
@@ -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
+ }
@@ -11,6 +11,7 @@
11
11
  #include "odf.h"
12
12
  #include "rtf.h"
13
13
  #include "critic.h"
14
+ #include "toc.h"
14
15
 
15
16
  char * export_node_tree(node *list, int format, unsigned long extensions);
16
17