rmultimarkdown 4.5.3.2 → 4.6.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,7 +14,7 @@
14
14
 
15
15
  #define TABSTOP 4
16
16
 
17
- #define MMD_VERSION "4.5.3"
17
+ #define MMD_VERSION "4.6"
18
18
 
19
19
  #define MMD_COPYRIGHT \
20
20
  "Copyright (c) 2013-2014 Fletcher T. Penney.\n\n" \
@@ -33,16 +33,6 @@
33
33
  /* This is the type used for the $$ pseudovariable passed to parents */
34
34
  #define YYSTYPE node *
35
35
 
36
- /* Define a structure to simplify handling of links */
37
- struct link_data {
38
- char *label; /* if this is a reference link */
39
- char *source; /* source URL */
40
- char *title; /* title string */
41
- node *attr; /* attribute tree */
42
- };
43
-
44
- typedef struct link_data link_data;
45
-
46
36
  /* This is the data we store in the parser context */
47
37
  typedef struct {
48
38
  char *charbuf; /* Input buffer */
@@ -69,6 +59,7 @@ typedef struct {
69
59
  node *links; /* ... links */
70
60
  node *glossary; /* ... glossary */
71
61
  node *citations; /* ... citations */
62
+ node *abbreviations; /* ... abbreviations */
72
63
  node *used_notes; /* notes that have been referenced */
73
64
  node *result_tree; /* reference to entire result tree */
74
65
  int footnote_to_print; /* set while we are printing so we can reverse link */
@@ -88,7 +79,7 @@ typedef struct {
88
79
  bool lyx_definition_hit; /* CRC - True when a definition has been encountered */
89
80
  bool lyx_definition_open; /* CRC - Have not completed a definition list entry */
90
81
  bool lyx_in_header; /* CRC - In a table header */
91
- bool lyx_fragile; /* CRC - in a beamer fragile frame */
82
+ bool lyx_in_frame; /* CRC - in a beamer frame */
92
83
  bool lyx_beamerbullet; /* CRC - beamer bullet list (add <+->) */
93
84
  int lyx_debug_nest; /* CRC - nesting level for enhanced debugging */
94
85
  bool lyx_table_need_line; /* CRC - need a line at the top */
@@ -158,6 +149,7 @@ link_data * extract_link_data(char *label, scratch_pad *scratch);
158
149
  node * mk_autolink(char *text);
159
150
 
160
151
  void extract_references(node *list, scratch_pad *scratch);
152
+ void extract_abbreviations(node *list, scratch_pad *scratch);
161
153
 
162
154
  bool extension(int ext, unsigned long extensions);
163
155
 
@@ -167,9 +159,13 @@ void trim_trailing_newlines(char *str);
167
159
 
168
160
  /* other utilities */
169
161
  char * label_from_string(char *str);
162
+ char * ascii_label_from_string(char *str);
170
163
  char * clean_string(char *str);
164
+ char * string_from_node_tree(node *n);
171
165
  char * label_from_node_tree(node *n);
172
166
  char * label_from_node(node *n);
167
+ char * ascii_label_from_node_tree(node *n);
168
+ char * ascii_label_from_node(node *n);
173
169
  void print_raw_node(GString *out, node *n);
174
170
  void print_raw_node_tree(GString *out, node*n);
175
171
 
@@ -135,6 +135,7 @@ void print_rtf_node(GString *out, node *n, scratch_pad *scratch) {
135
135
  scratch->odf_para_type = old_type;
136
136
  break;
137
137
  case VERBATIM:
138
+ case VERBATIMFENCE:
138
139
  pad_rtf(out, 2, scratch);
139
140
  g_string_append_printf(out, "{\\pard " kCodeStyle);
140
141
  print_rtf_code_string(out,n->str,scratch);
@@ -157,6 +158,7 @@ void print_rtf_node(GString *out, node *n, scratch_pad *scratch) {
157
158
  break;
158
159
  case CODE:
159
160
  case VERBATIM:
161
+ case VERBATIMFENCE:
160
162
  g_string_append_printf(out, "{\\pard " kCodeStyle);
161
163
  break;
162
164
  default:
@@ -379,7 +381,7 @@ void print_rtf_node(GString *out, node *n, scratch_pad *scratch) {
379
381
  scratch->odf_para_type = CITATION;
380
382
 
381
383
  /* change to represent cite count only */
382
- lev = cite_count_node_from_end(temp_node);
384
+ // lev = cite_count_node_from_end(temp_node);
383
385
  g_string_append_printf(out, "{\\super\\chftn}{\\footnote\\ftnalt\\pard\\plain\\chtfn ");
384
386
  scratch->padded = 2;
385
387
  if (temp_node->children != NULL) {
@@ -392,7 +394,7 @@ void print_rtf_node(GString *out, node *n, scratch_pad *scratch) {
392
394
  /* We are reusing a previous citation */
393
395
 
394
396
  /* Change lev to represent cite count only */
395
- lev = cite_count_node_from_end(temp_node);
397
+ // lev = cite_count_node_from_end(temp_node);
396
398
 
397
399
  g_string_append_printf(out, "REUSE CITATION");
398
400
  }
@@ -449,6 +451,7 @@ void print_rtf_node(GString *out, node *n, scratch_pad *scratch) {
449
451
  g_string_append_printf(out, "\\\n");
450
452
  break;
451
453
  case NOTELABEL:
454
+ case GLOSSARYLABEL:
452
455
  case FOOTER:
453
456
  case LINKREFERENCE:
454
457
  break;
@@ -116,7 +116,7 @@ void transclude_source(GString *source, char *basedir, char *stack, int output_f
116
116
  g_string_append_c(folder, '/');
117
117
  }
118
118
 
119
- //fprintf(stderr, "Transclude using '%s'\n", folder->str);
119
+ /* fprintf(stderr, "Transclude using '%s'\n", folder->str); */
120
120
 
121
121
  /* Iterate through {{foo.txt}} and substitute contents of file without metadata */
122
122
 
@@ -127,92 +127,108 @@ void transclude_source(GString *source, char *basedir, char *stack, int output_f
127
127
  if (stop == NULL)
128
128
  break;
129
129
 
130
- // TODO: Need to check that we found something reasonable
131
-
132
- strncpy(real,start+2,stop-start-2);
133
- real[stop-start-2] = '\0';
134
-
135
- filename = g_string_new(folder->str);
136
- g_string_append_printf(filename, "%s",real);
137
-
138
- /* Adjust for wildcard extensions */
139
- /* But not if output_format == 0 */
140
- if (output_format && strncmp(&filename->str[strlen(filename->str) - 2],".*",2) == 0) {
141
- g_string_erase(filename, strlen(filename->str) - 2, 2);
142
- if (output_format == TEXT_FORMAT) {
143
- g_string_append(filename,".txt");
144
- } else if (output_format == HTML_FORMAT) {
145
- g_string_append(filename,".html");
146
- } else if (output_format == LATEX_FORMAT) {
147
- g_string_append(filename,".tex");
148
- } else if (output_format == BEAMER_FORMAT) {
149
- g_string_append(filename,".tex");
150
- } else if (output_format == MEMOIR_FORMAT) {
151
- g_string_append(filename,".tex");
152
- } else if (output_format == ODF_FORMAT) {
153
- g_string_append(filename,".fodt");
154
- } else if (output_format == OPML_FORMAT) {
155
- g_string_append(filename,".opml");
156
- } else if (output_format == LYX_FORMAT) {
157
- g_string_append(filename,".lyx");
158
- } else if (output_format == RTF_FORMAT) {
159
- g_string_append(filename,".rtf");
160
- } else {
161
- /* default extension -- in this case we only have 1 */
162
- g_string_append(filename,".txt");
130
+ /* Check that we found something reasonable -- we cap at 1000 characters */
131
+ if (stop - start < 1000) {
132
+ strncpy(real,start+2,stop-start-2);
133
+ real[stop-start-2] = '\0';
134
+
135
+ filename = g_string_new(folder->str);
136
+ g_string_append_printf(filename, "%s",real);
137
+
138
+ /* Adjust for wildcard extensions */
139
+ /* But not if output_format == 0 */
140
+ if (output_format && strncmp(&filename->str[strlen(filename->str) - 2],".*",2) == 0) {
141
+ g_string_erase(filename, strlen(filename->str) - 2, 2);
142
+ if (output_format == TEXT_FORMAT) {
143
+ g_string_append(filename,".txt");
144
+ } else if (output_format == HTML_FORMAT) {
145
+ g_string_append(filename,".html");
146
+ } else if (output_format == LATEX_FORMAT) {
147
+ g_string_append(filename,".tex");
148
+ } else if (output_format == BEAMER_FORMAT) {
149
+ g_string_append(filename,".tex");
150
+ } else if (output_format == MEMOIR_FORMAT) {
151
+ g_string_append(filename,".tex");
152
+ } else if (output_format == ODF_FORMAT) {
153
+ g_string_append(filename,".fodt");
154
+ } else if (output_format == OPML_FORMAT) {
155
+ g_string_append(filename,".opml");
156
+ } else if (output_format == LYX_FORMAT) {
157
+ g_string_append(filename,".lyx");
158
+ } else if (output_format == RTF_FORMAT) {
159
+ g_string_append(filename,".rtf");
160
+ } else {
161
+ /* default extension -- in this case we only have 1 */
162
+ g_string_append(filename,".txt");
163
+ }
163
164
  }
164
- }
165
165
 
166
- pos = stop - source->str;
166
+ pos = stop - source->str;
167
167
 
168
- /* Don't reparse ourselves */
169
- if (stack != NULL) {
170
- temp = strstr(stack,filename->str);
168
+ /* Don't reparse ourselves */
169
+ if (stack != NULL) {
170
+ temp = strstr(stack,filename->str);
171
171
 
172
- if ((temp != NULL) && (temp[strlen(filename->str)] == '\n')){
173
- start = strstr(source->str + pos,"{{");
174
- g_string_free(filename, true);
175
- continue;
172
+ if ((temp != NULL) && (temp[strlen(filename->str)] == '\n')){
173
+ start = strstr(source->str + pos,"{{");
174
+ g_string_free(filename, true);
175
+ continue;
176
+ }
176
177
  }
177
- }
178
178
 
179
- /* Read file */
180
- if ((input = fopen(filename->str, "r")) != NULL ) {
181
- filebuffer = g_string_new("");
179
+ /* Read file */
180
+ if ((input = fopen(filename->str, "r")) != NULL ) {
181
+ filebuffer = g_string_new("");
182
182
 
183
- while ((curchar = fgetc(input)) != EOF)
184
- g_string_append_c(filebuffer, curchar);
185
-
186
- fclose(input);
183
+ while ((curchar = fgetc(input)) != EOF)
184
+ g_string_append_c(filebuffer, curchar);
185
+
186
+ fclose(input);
187
187
 
188
- pos = start - source->str;
188
+ pos = start - source->str;
189
189
 
190
- g_string_erase(source, pos, 2 + stop - start);
190
+ g_string_erase(source, pos, 2 + stop - start);
191
191
 
192
- /* Update stack list */
193
- stackstring = g_string_new(stack);
194
- g_string_append_printf(stackstring,"%s\n",filename->str);
192
+ /* Update stack list */
193
+ stackstring = g_string_new(stack);
194
+ g_string_append_printf(stackstring,"%s\n",filename->str);
195
195
 
196
196
 
197
- /* Recursively transclude files */
198
- transclude_source(filebuffer, folder->str, stackstring->str, output_format);
197
+ /* Recursively transclude files */
198
+ transclude_source(filebuffer, folder->str, stackstring->str, output_format);
199
199
 
200
- temp = source_without_metadata(filebuffer->str, 0x000000);
200
+ temp = source_without_metadata(filebuffer->str, 0x000000);
201
201
 
202
- g_string_insert(source, pos, temp);
202
+ g_string_insert(source, pos, temp);
203
203
 
204
- pos += strlen(temp);
205
- g_string_free(filebuffer, true);
206
- g_string_free(stackstring, true);
207
- } else {
208
- /* fprintf(stderr, "error opening file: %s\n", filename->str); */
209
- }
204
+ pos += strlen(temp);
205
+ g_string_free(filebuffer, true);
206
+ g_string_free(stackstring, true);
207
+ } else {
208
+ /* fprintf(stderr, "error opening file: %s\n", filename->str); */
209
+ }
210
210
 
211
+ g_string_free(filename, true);
212
+ } else {
213
+ /* Our "match" was > 1000 characters long */
214
+ pos = stop - source->str;
215
+ }
211
216
  start = strstr(source->str + pos,"{{");
212
- g_string_free(filename, true);
213
217
  }
214
218
 
215
219
  g_string_free(folder, true);
216
220
  free(path);
217
221
  free(base);
218
222
  }
223
+
224
+ /* Allow for a footer to specify files to be appended to the end of the text, and then transcluded.
225
+ Useful for appending a list of footnotes, citations, abbreviations, etc. to each separate file,
226
+ but not including multiple copies when processing the master file. */
227
+ void append_mmd_footers(GString *source) {
228
+ /* Look for mmd_footer metadata */
229
+ if (has_metadata(source->str, 0x000000)) {
230
+ char *meta = extract_metadata_value(source->str, 0x000000, "mmdfooter");
231
+ if (meta != NULL)
232
+ g_string_append_printf(source, "\n\n{{%s}}\n",meta);
233
+ }
234
+ }
@@ -24,3 +24,4 @@
24
24
 
25
25
  char * source_without_metadata(char * source, unsigned long extensions);
26
26
  void transclude_source(GString *source, char *basedir, char *stack, int format);
27
+ void append_mmd_footers(GString *source);
@@ -36,12 +36,19 @@ char * export_node_tree(node *list, int format, unsigned long extensions) {
36
36
  #ifdef DEBUG_ON
37
37
  fprintf(stderr, "extract_references\n");
38
38
  #endif
39
- /* Parse for link, images, etc reference definitions */
39
+
40
40
  if ((format != OPML_FORMAT) &&
41
41
  (format != CRITIC_ACCEPT_FORMAT) &&
42
42
  (format != CRITIC_REJECT_FORMAT) &&
43
- (format != CRITIC_HTML_HIGHLIGHT_FORMAT))
43
+ (format != CRITIC_HTML_HIGHLIGHT_FORMAT)) {
44
+ /* Parse for link, images, etc reference definitions */
44
45
  extract_references(list, scratch);
46
+
47
+ /* Find defined abbreviations */
48
+ extract_abbreviations(list, scratch);
49
+ /* Apply those abbreviations to source text */
50
+ find_abbreviations(list, scratch);
51
+ }
45
52
 
46
53
  /* Change our desired format based on metadata */
47
54
  if (format == LATEX_FORMAT)
@@ -76,12 +83,21 @@ char * export_node_tree(node *list, int format, unsigned long extensions) {
76
83
  #endif
77
84
  break;
78
85
  case LATEX_FORMAT:
86
+ if ((list != NULL) && (list->key != METADATA)) {
87
+ print_latex_node_tree(out, scratch->abbreviations, scratch);
88
+ }
79
89
  print_latex_node_tree(out, list, scratch);
80
90
  break;
81
91
  case MEMOIR_FORMAT:
92
+ if ((list != NULL) && (list->key != METADATA)) {
93
+ print_memoir_node_tree(out, scratch->abbreviations, scratch);
94
+ }
82
95
  print_memoir_node_tree(out, list, scratch);
83
96
  break;
84
97
  case BEAMER_FORMAT:
98
+ if ((list != NULL) && (list->key != METADATA)) {
99
+ print_beamer_node_tree(out, scratch->abbreviations, scratch);
100
+ }
85
101
  print_beamer_node_tree(out, list, scratch);
86
102
  break;
87
103
  case LYX_FORMAT:
@@ -194,6 +210,106 @@ void extract_references(node *list, scratch_pad *scratch) {
194
210
  }
195
211
  }
196
212
 
213
+ /* extract_abbreviations -- traverse node tree and find abbreviation definitions */
214
+ void extract_abbreviations(node *list, scratch_pad *scratch) {
215
+ node *temp;
216
+
217
+ while (list != NULL) {
218
+ switch (list->key) {
219
+ case ABBREVIATION:
220
+ temp = copy_node(list);
221
+ list->key = KEY_COUNTER; /* Mark this as dead; we will use it elsewhere */
222
+ trim_trailing_whitespace(temp->str);
223
+ scratch->abbreviations = cons(temp, scratch->abbreviations);
224
+ break;
225
+ case HEADINGSECTION:
226
+ case RAW:
227
+ case LIST:
228
+ extract_abbreviations(list->children, scratch);
229
+ break;
230
+ default:
231
+ /* Try to boost performance by skipping dead ends */
232
+ break;
233
+ }
234
+ list = list->next;
235
+ }
236
+ }
237
+
238
+
239
+ /* find_abbreviations -- use abbreviations to look for matching strings */
240
+ void find_abbreviations(node *list, scratch_pad *scratch) {
241
+ node *abbr = scratch->abbreviations;
242
+ node *temp, *target, *end = NULL;
243
+ bool ismatch;
244
+
245
+ // Don't look if we didn't define any abbreviations */
246
+ if (abbr->key == KEY_COUNTER)
247
+ return;
248
+
249
+ while (list != NULL) {
250
+ switch (list->key) {
251
+ case STR:
252
+ /* Look for matching abbrevation */
253
+ /*fprintf(stderr, "Check '%s' for matching abbr\n", list->str); */
254
+ abbr = scratch->abbreviations;
255
+ while (abbr != NULL) {
256
+ if (abbr->key != KEY_COUNTER) {
257
+ ismatch = true;
258
+ temp = abbr->children->children;
259
+ target = list;
260
+
261
+ while((ismatch) && (temp != NULL) && (target != NULL)) {
262
+ switch (temp->key) {
263
+ case STR:
264
+ if (strcmp(temp->str, target->str) != 0) {
265
+ ismatch = false;
266
+ }
267
+ case SPACE:
268
+ case KEY_COUNTER:
269
+ break;
270
+ default:
271
+ if (temp->key != target->key)
272
+ ismatch = false;
273
+ break;
274
+ }
275
+ temp = temp->next;
276
+ end = target;
277
+ target = target->next;
278
+ }
279
+ if ((ismatch) && (temp == NULL)) {
280
+ temp = copy_node(abbr);
281
+ temp->next = NULL;
282
+ list->children = temp;
283
+ if (list != end) {
284
+ list->key = ABBRSTART;
285
+ if (end != NULL)
286
+ end->key = ABBRSTOP;
287
+ } else {
288
+ list->key = ABBR;
289
+ }
290
+ }
291
+ }
292
+ abbr = abbr->next;
293
+ }
294
+ break;
295
+ case LIST:
296
+ case HEADINGSECTION:
297
+ case PARA:
298
+ case LINK:
299
+ case LINKREFERENCE:
300
+ case NOTEREFERENCE:
301
+ /* Check children of these elements */
302
+ find_abbreviations(list->children, scratch);
303
+ break;
304
+ default:
305
+ /* Everything else we skip */
306
+ break;
307
+ }
308
+ list = list->next;
309
+ }
310
+ }
311
+
312
+
197
313
  /* extract_link_data -- given a label, parse the link data and return */
198
314
  link_data * extract_link_data(char *label, scratch_pad *scratch) {
199
315
  char *temp;
@@ -15,6 +15,9 @@
15
15
  char * export_node_tree(node *list, int format, unsigned long extensions);
16
16
 
17
17
  void extract_references(node *list, scratch_pad *scratch);
18
+ void extract_abbreviations(node *list, scratch_pad *scratch);
19
+ void find_abbreviations(node *list, scratch_pad *scratch);
20
+
18
21
  link_data * extract_link_data(char *label, scratch_pad *scratch);
19
22
 
20
23
  void pad(GString *out, int num, scratch_pad *scratch);