rmultimarkdown 4.5.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/LICENSE +75 -0
  2. data/MultiMarkdown-4/GLibFacade.c +294 -0
  3. data/MultiMarkdown-4/GLibFacade.h +95 -0
  4. data/MultiMarkdown-4/beamer.c +179 -0
  5. data/MultiMarkdown-4/beamer.h +11 -0
  6. data/MultiMarkdown-4/critic.c +111 -0
  7. data/MultiMarkdown-4/critic.h +15 -0
  8. data/MultiMarkdown-4/glib.h +11 -0
  9. data/MultiMarkdown-4/html.c +1062 -0
  10. data/MultiMarkdown-4/html.h +14 -0
  11. data/MultiMarkdown-4/latex.c +1137 -0
  12. data/MultiMarkdown-4/latex.h +16 -0
  13. data/MultiMarkdown-4/libMultiMarkdown.h +157 -0
  14. data/MultiMarkdown-4/lyx.c +2163 -0
  15. data/MultiMarkdown-4/lyx.h +36 -0
  16. data/MultiMarkdown-4/lyxbeamer.c +267 -0
  17. data/MultiMarkdown-4/lyxbeamer.h +11 -0
  18. data/MultiMarkdown-4/memoir.c +79 -0
  19. data/MultiMarkdown-4/memoir.h +10 -0
  20. data/MultiMarkdown-4/multimarkdown.c +469 -0
  21. data/MultiMarkdown-4/odf.c +1202 -0
  22. data/MultiMarkdown-4/odf.h +18 -0
  23. data/MultiMarkdown-4/opml.c +188 -0
  24. data/MultiMarkdown-4/opml.h +15 -0
  25. data/MultiMarkdown-4/parse_utilities.c +752 -0
  26. data/MultiMarkdown-4/parser.c +15679 -0
  27. data/MultiMarkdown-4/parser.h +188 -0
  28. data/MultiMarkdown-4/rng.c +117 -0
  29. data/MultiMarkdown-4/rtf.c +648 -0
  30. data/MultiMarkdown-4/rtf.h +17 -0
  31. data/MultiMarkdown-4/strtok.c +56 -0
  32. data/MultiMarkdown-4/strtok.h +9 -0
  33. data/MultiMarkdown-4/text.c +53 -0
  34. data/MultiMarkdown-4/text.h +11 -0
  35. data/MultiMarkdown-4/transclude.c +218 -0
  36. data/MultiMarkdown-4/transclude.h +26 -0
  37. data/MultiMarkdown-4/writer.c +576 -0
  38. data/MultiMarkdown-4/writer.h +34 -0
  39. data/README.md +75 -0
  40. data/Rakefile +85 -0
  41. data/bin/rmultimarkdown +128 -0
  42. data/ext/extconf.h +3 -0
  43. data/ext/extconf.rb +10 -0
  44. data/ext/multi_markdown.c +100 -0
  45. data/lib/multi_markdown.bundle +0 -0
  46. data/lib/multi_markdown.rb +88 -0
  47. data/lib/multi_markdown/version.rb +6 -0
  48. data/lib/rmultimarkdown.rb +1 -0
  49. data/rmultimarkdown.gemspec +37 -0
  50. data/test/multi_markdown_test.rb +64 -0
  51. metadata +122 -0
@@ -0,0 +1,36 @@
1
+ #ifndef LYX_PARSER_H
2
+ #define LYX_PARSER_H
3
+
4
+ #include "parser.h"
5
+ #include "writer.h"
6
+
7
+ /* allow the user to change the heading levels */
8
+
9
+ extern GString *heading_name[7];
10
+
11
+ /* Lyx likes to wrap strings in "environments" */
12
+ enum lyx_environment{
13
+ LYX_NONE,
14
+ LYX_STANDARD,
15
+ LYX_CODE,
16
+ LYX_PLAIN
17
+ };
18
+
19
+
20
+ void perform_lyx_output(GString *out, node* list, scratch_pad *scratch);
21
+ bool begin_lyx_output(GString *out, node* list, scratch_pad *scratch);
22
+ void print_lyx_node_tree(GString *out, node *list, scratch_pad *scratch, bool no_newline);
23
+ void end_lyx_output(GString *out, node* list, scratch_pad *scratch);
24
+ void print_lyx_node(GString *out, node *n, scratch_pad *scratch, bool no_newline);
25
+ void print_lyx_localized_typography(GString *out, unsigned char character, scratch_pad *scratch);
26
+ void print_lyx_string(GString *out,char *str, scratch_pad *scratch,short environment);
27
+ void print_lyx_url(GString *out, char *str, scratch_pad *scratch);
28
+ void print_lyx_endnotes(GString *out, scratch_pad *scratch);
29
+ void lyx_get_table_dimensions(node* list, int *rows, int *cols, scratch_pad *scratch);
30
+ void add_prefixes(node *list, node *root, scratch_pad *scratch);
31
+ void update_links(char *label,char *prefix, scratch_pad *scratch);
32
+ char *prefix_label(char *prefix, char *label, bool pound);
33
+ void update_link_source(char *source, char *prefix,node *n);
34
+ void print_escaped_node_tree(GString *out, node *n);
35
+ void print_escaped_node(GString *out, node *n);
36
+ #endif
@@ -0,0 +1,267 @@
1
+ /*
2
+
3
+ lyxbeamer.c -- Beamer add-on to LyX writer
4
+
5
+ (c) 2013 Charles R. Cowan
6
+ (c) 2013 Fletcher T. Penney (http://fletcherpenney.net/).
7
+
8
+ Derrived from MultiMarkdown by Fletcher T. Penney - added code to support the LYY format directly
9
+
10
+ This program is free software; you can redistribute it and/or modify
11
+ it under the terms of the GNU General Public License or the MIT
12
+ license. See LICENSE for details.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ */
20
+
21
+ #include "lyxbeamer.h"
22
+ #include "lyx.h"
23
+
24
+ /* print_beamer_node_tree -- convert node tree to LyX */
25
+ void print_lyxbeamer_node_tree(GString *out, node *list, scratch_pad *scratch, bool no_newline) {
26
+ while (list != NULL) {
27
+ print_lyxbeamer_node(out, list, scratch, no_newline);
28
+ list = list->next;
29
+ }
30
+ }
31
+
32
+ /* print_beamer_node -- convert given node to LyX and append */
33
+ void print_lyxbeamer_node(GString *out, node *n, scratch_pad *scratch, bool no_newline) {
34
+ int lev;
35
+ int i;
36
+ char *temp;
37
+ char *prefixed_label;
38
+ node *temp_node;
39
+ int old_type;
40
+
41
+ /* If we are forcing a complete document, and METADATA isn't the first thing,
42
+ we need to close <head> */
43
+ if ((scratch->extensions & EXT_COMPLETE)
44
+ && !(scratch->extensions & EXT_HEAD_CLOSED) &&
45
+ !((n->key == FOOTER) || (n->key == METADATA))) {
46
+ scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED;
47
+ }
48
+ switch (n->key) {
49
+ case FOOTER:
50
+ if (scratch->lyx_fragile){ // have an open fragile
51
+ g_string_append(out,"\n\\end_inset");
52
+ g_string_append(out,"\n\\end_layout");
53
+ }
54
+ scratch->lyx_fragile = FALSE;
55
+ print_lyxbeamer_endnotes(out, scratch);
56
+ break;
57
+ case BULLETLIST:
58
+ case ORDEREDLIST:
59
+ case DEFLIST:
60
+ old_type = scratch->lyx_para_type;
61
+ scratch->lyx_para_type = n->key;
62
+ scratch->lyx_level++;
63
+ if (scratch->lyx_level > 1){
64
+ g_string_append(out,"\n\\begin_deeper\n");
65
+ }
66
+ print_lyxbeamer_node_tree(out, n->children, scratch, FALSE);
67
+ scratch->lyx_level--;
68
+ if (scratch->lyx_level > 0){
69
+ g_string_append(out,"\n\\end_deeper\n");
70
+ }
71
+ scratch->lyx_para_type = old_type;
72
+ if (scratch->lyx_definition_open){
73
+ g_string_append(out,"\n\\end_deeper\n");
74
+ scratch->lyx_definition_open = FALSE;
75
+ }
76
+ break;
77
+ case LISTITEM:
78
+ scratch-> lyx_beamerbullet = TRUE;
79
+ temp_node = n-> children; // should be a list node
80
+ if (temp_node->key != LIST){
81
+ fprintf(stderr,"\nUnanticipated List Item Format");
82
+ exit(EXIT_FAILURE);
83
+ } else {
84
+ temp_node = temp_node-> children; // process the list
85
+ i = 0;
86
+ while (temp_node != NULL){
87
+ i++;
88
+ if (i == 2){
89
+ g_string_append(out,"\n\\begin_deeper\n");
90
+ old_type = scratch->lyx_para_type;
91
+ scratch->lyx_para_type = PARA; // and make it a paragraph, not a list item
92
+ }
93
+ print_lyx_node(out, temp_node, scratch, no_newline);
94
+ temp_node = temp_node->next;
95
+
96
+ }
97
+ if (i>1){
98
+ scratch->lyx_para_type = old_type; // reset the paragraph type
99
+ g_string_append(out,"\n\\end_deeper\n");
100
+ }
101
+ }
102
+ scratch-> lyx_beamerbullet = TRUE;
103
+ break;
104
+ case HEADINGSECTION:
105
+ if (scratch->lyx_fragile){ // have an open fragile
106
+ g_string_append(out,"\n\\end_inset");
107
+ g_string_append(out,"\n\\end_layout");
108
+ }
109
+ scratch->lyx_fragile = FALSE;
110
+ if (tree_contains_key(n->children,VERBATIM)) {
111
+ scratch->lyx_fragile = TRUE;
112
+ }
113
+ print_lyxbeamer_node_tree(out,n->children,scratch , FALSE);
114
+ break;
115
+ case H1: case H2: case H3: case H4: case H5: case H6:
116
+ lev = n->key - H1 + scratch->baseheaderlevel; /* assumes H1 ... H6 are in order */
117
+ switch (lev) {
118
+ case 1:
119
+ g_string_append(out, "\n\\begin_layout Part\n");
120
+ break;
121
+ case 2:
122
+ g_string_append(out, "\n\\begin_layout Section\n");
123
+ break;
124
+ case 3:
125
+ if (scratch->lyx_fragile) {
126
+ g_string_append(out, "\n\\begin_layout EndFrame");
127
+ g_string_append(out, "\n\\end_layout");
128
+ g_string_append(out, "\n\\begin_layout Standard");
129
+ g_string_append(out,"\n\\begin_inset Flex FragileFrame");
130
+ g_string_append(out,"\nstatus open\n\n");
131
+ g_string_append(out,"\n\\begin_layout Plain Layout\n");
132
+ g_string_append(out,"\n\\begin_inset Flex FragileTitle");
133
+ g_string_append(out,"\nstatus open\n\n");
134
+ g_string_append(out,"\n\\begin_layout Plain Layout\n");
135
+
136
+ } else {
137
+ g_string_append(out, "\n\\begin_layout BeginFrame\n");
138
+ }
139
+ break;
140
+ case 4:
141
+ g_string_append(out,"\n\\begin_layout Standard");
142
+ g_string_append(out, "\n\\begin_inset Flex ArticleMode");
143
+ g_string_append(out, "\nstatus open\n\n");
144
+ g_string_append(out,"\n\\begin_layout Plain Layout\n");
145
+ break;
146
+ default:
147
+ g_string_append(out,"\n\\begin_layout Standard");
148
+ g_string_append(out, "\n\\emph on\n");
149
+ break;
150
+ }
151
+ /* Don't allow footnotes */
152
+ scratch->no_lyx_footnote = TRUE;
153
+ if (n->children->key == AUTOLABEL) {
154
+ /* use label for header since one was specified (MMD)*/
155
+ temp = label_from_string(n->children->str);
156
+ prefixed_label = prefix_label(heading_name[lev-1]->str,temp,FALSE);
157
+ print_lyx_node_tree(out, n->children->next, scratch , FALSE);
158
+ g_string_append(out,"\n\\begin_inset CommandInset label\n");
159
+ g_string_append(out,"LatexCommand label\n");
160
+ g_string_append_printf(out, "name \"%s\"",prefixed_label);
161
+ g_string_append(out,"\n\\end_inset\n");
162
+ free(prefixed_label);
163
+ free(temp);
164
+ } else {
165
+ /* generate a label by default for MMD */
166
+ temp = label_from_node_tree(n->children);
167
+ prefixed_label = prefix_label(heading_name[lev-1]->str,temp,FALSE);
168
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
169
+ g_string_append(out,"\n\\begin_inset CommandInset label\n");
170
+ g_string_append(out,"LatexCommand label\n");
171
+ g_string_append_printf(out, "name \"%s\"",prefixed_label);
172
+ g_string_append(out,"\n\\end_inset\n");
173
+ free(prefixed_label);
174
+ free(temp);
175
+ }
176
+ scratch->no_lyx_footnote = FALSE;
177
+ switch(lev){
178
+ case 1: case 2:
179
+ g_string_append(out,"\n\\end_layout\n");
180
+ break;
181
+ case 3:
182
+ if (scratch->lyx_fragile){
183
+ g_string_append(out,"\n\\end_layout");
184
+ g_string_append(out,"\n\\end_inset");
185
+ g_string_append(out,"\n\\end_layout\n");
186
+ } else{
187
+ g_string_append(out, "\n\\end_layout\n");
188
+ }
189
+ break;
190
+ case 4:
191
+ g_string_append(out,"\n\\end_layout");
192
+ g_string_append(out,"\n\\end_inset");
193
+ g_string_append(out,"\n\\end_layout");
194
+ break;
195
+ default:
196
+ g_string_append(out, "\n\\emph default\n");
197
+ g_string_append(out,"\n\\end_layout");
198
+ break;
199
+ }
200
+
201
+ break;
202
+ default:
203
+ /* most things are not changed for beamer output */
204
+ print_lyx_node(out, n, scratch,no_newline);
205
+ }
206
+ }
207
+
208
+ /* print_beamer_endnotes */
209
+ void print_lyxbeamer_endnotes(GString *out, scratch_pad *scratch) {
210
+ node *temp_node;
211
+ scratch->used_notes = reverse_list(scratch->used_notes);
212
+ node *note = scratch->used_notes;
213
+
214
+ // Handle Glossary
215
+ temp_node = note;
216
+ while (temp_node != NULL){
217
+ if(temp_node->key == GLOSSARYSOURCE){
218
+ g_string_append(out, "\n\\begin_layout BeginFrame\nGlossary\n");
219
+ g_string_append(out,"\n\\begin_layout Standard");
220
+ g_string_append(out,"\n\\begin_inset CommandInset nomencl_print");
221
+ g_string_append(out,"\nLatexCommand printnomenclature");
222
+ g_string_append(out,"\nset_width \"auto\"\n");
223
+ g_string_append(out,"\n\\end_inset\n");
224
+ g_string_append(out,"\n\\end_layout\n");
225
+ g_string_append(out, "\n\\end_layout\n");
226
+ g_string_append(out, "\n\\begin_layout EndFrame");
227
+ g_string_append(out, "\n\\end_layout");
228
+ break;
229
+ }
230
+ temp_node = temp_node->next;
231
+ }
232
+
233
+ if (note == NULL)
234
+ return;
235
+
236
+ note = scratch->used_notes;
237
+
238
+ if (tree_contains_key(note,CITATIONSOURCE)){
239
+ g_string_append(out, "\n\\begin_layout BeginFrame\nReferences\n");
240
+ g_string_append(out, "\n\\end_layout");
241
+ }
242
+ while ( note != NULL) {
243
+ if (note->key == KEY_COUNTER) {
244
+ note = note->next;
245
+ continue;
246
+ }
247
+
248
+
249
+ if (note->key == CITATIONSOURCE) {
250
+ g_string_append(out, "\n\\begin_layout Bibliography\n");
251
+ g_string_append(out,"\\begin_inset CommandInset bibitem\n");
252
+ g_string_append(out,"LatexCommand bibitem\n");
253
+ g_string_append_printf(out, "key \"%s\"\n", note->str);
254
+ g_string_append_printf(out, "label \"%s\"\n", note->str);
255
+ g_string_append(out,"\n\\end_inset\n");
256
+ print_lyx_node(out, note, scratch, FALSE);
257
+ g_string_append(out,"\n\\end_layout\n");
258
+ } else {
259
+ /* footnotes handled elsewhere */
260
+ }
261
+
262
+ note = note->next;
263
+ }
264
+ g_string_append(out, "\n\\begin_layout EndFrame"); // close last frame
265
+ g_string_append(out, "\n\\end_layout");
266
+
267
+ }
@@ -0,0 +1,11 @@
1
+ #ifndef LYX_BEAMER_PARSER_H
2
+ #define LYX_BEAMER_PARSER_H
3
+
4
+ #include "parser.h"
5
+ #include "lyx.h"
6
+
7
+ void print_lyxbeamer_node_tree(GString *out, node *list, scratch_pad *scratch,bool no_newline);
8
+ void print_lyxbeamer_node(GString *out, node *n, scratch_pad *scratch,bool no_newline);
9
+ void print_lyxbeamer_endnotes(GString *out, scratch_pad *scratch);
10
+
11
+ #endif
@@ -0,0 +1,79 @@
1
+ /*
2
+
3
+ memoir.c -- Memoir add-on to LaTeX writer
4
+
5
+ (c) 2013 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 "memoir.h"
19
+
20
+ /* print_memoir_node_tree -- convert node tree to LaTeX */
21
+ void print_memoir_node_tree(GString *out, node *list, scratch_pad *scratch) {
22
+ while (list != NULL) {
23
+ print_memoir_node(out, list, scratch);
24
+ list = list->next;
25
+ }
26
+ }
27
+
28
+ /* print_memoir_node -- convert given node to LaTeX and append */
29
+ void print_memoir_node(GString *out, node *n, scratch_pad *scratch) {
30
+
31
+ /* If we are forcing a complete document, and METADATA isn't the first thing,
32
+ we need to close <head> */
33
+ if ((scratch->extensions & EXT_COMPLETE)
34
+ && !(scratch->extensions & EXT_HEAD_CLOSED) &&
35
+ !((n->key == FOOTER) || (n->key == METADATA))) {
36
+ pad(out, 2, scratch);
37
+ scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED;
38
+ }
39
+ switch (n->key) {
40
+ case VERBATIM:
41
+ pad(out, 2, scratch);
42
+ if ((n->children != NULL) && (n->children->key == VERBATIMTYPE)) {
43
+ trim_trailing_whitespace(n->children->str);
44
+ if (strlen(n->children->str) > 0) {
45
+ g_string_append_printf(out, "\\begin{adjustwidth}{2.5em}{2.5em}\n\\begin{lstlisting}[language=%s]\n", n->children->str);
46
+ print_raw_node(out, n);
47
+ g_string_append_printf(out, "\n\\end{lstlisting}\n\\end{adjustwidth}");
48
+ scratch->padded = 0;
49
+ break;
50
+ }
51
+ }
52
+ g_string_append_printf(out, "\\begin{adjustwidth}{2.5em}{2.5em}\n\\begin{verbatim}\n\n");
53
+ print_raw_node(out, n);
54
+ g_string_append_printf(out, "\n\\end{verbatim}\n\\end{adjustwidth}");
55
+ scratch->padded = 0;
56
+ break;
57
+ case HEADINGSECTION:
58
+ print_memoir_node_tree(out, n->children, scratch);
59
+ break;
60
+ case DEFLIST:
61
+ pad(out, 2, scratch);
62
+ g_string_append_printf(out, "\\begin{description}");
63
+ scratch->padded = 0;
64
+ print_memoir_node_tree(out, n->children, scratch);
65
+ pad(out, 1, scratch);
66
+ g_string_append_printf(out, "\\end{description}");
67
+ scratch->padded = 0;
68
+ break;
69
+ case DEFINITION:
70
+ pad(out, 2, scratch);
71
+ scratch->padded = 2;
72
+ print_memoir_node_tree(out, n->children, scratch);
73
+ scratch->padded = 0;
74
+ break;
75
+ default:
76
+ /* most things are not changed for memoir output */
77
+ print_latex_node(out, n, scratch);
78
+ }
79
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef MEMOIR_PARSER_H
2
+ #define MEMOIR_PARSER_H
3
+
4
+ #include "parser.h"
5
+ #include "latex.h"
6
+
7
+ void print_memoir_node_tree(GString *out, node *list, scratch_pad *scratch);
8
+ void print_memoir_node(GString *out, node *n, scratch_pad *scratch);
9
+
10
+ #endif
@@ -0,0 +1,469 @@
1
+ /*
2
+
3
+ parser.leg -> parser.c -- Parse (Multi)Markdown plain text for
4
+ conversion into other formats
5
+
6
+ (c) 2013 Fletcher T. Penney (http://fletcherpenney.net/).
7
+
8
+ Derived from peg-multimarkdown, which was forked from peg-markdown,
9
+ which is (c) 2008 John MacFarlane (jgm at berkeley dot edu), and
10
+ licensed under GNU GPL or MIT.
11
+
12
+ This program is free software; you can redistribute it and/or modify
13
+ it under the terms of the GNU General Public License or the MIT
14
+ license. See LICENSE for details.
15
+
16
+ This program is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU General Public License for more details.
20
+ */
21
+
22
+ #include <getopt.h>
23
+ #include <libgen.h>
24
+ #include "parser.h"
25
+ #include "transclude.h"
26
+
27
+ int main(int argc, char **argv)
28
+ {
29
+ int numargs;
30
+ int c;
31
+ int i;
32
+ static int batch_flag = 0;
33
+ static int complete_flag = 0;
34
+ static int snippet_flag = 0;
35
+ static int compatibility_flag = 0;
36
+ static int notes_flag = 0;
37
+ static int no_notes_flag = 0;
38
+ static int typography_flag = 0;
39
+ static int no_typography_flag = 0;
40
+ static int label_flag = 0;
41
+ static int no_label_flag = 0;
42
+ static int escaped_line_breaks_flag = 0;
43
+ static int obfuscate_flag = 0;
44
+ static int no_obfuscate_flag = 0;
45
+ static int process_html_flag = 0;
46
+ static int random_footnotes_flag = 0;
47
+ bool list_meta_keys = 0;
48
+ char *target_meta_key = FALSE;
49
+
50
+ static struct option long_options[] = {
51
+ {"batch", no_argument, &batch_flag, 1}, /* process each file separately */
52
+ {"to", required_argument, 0, 't'}, /* which output format to use */
53
+ {"full", no_argument, &complete_flag, 1}, /* complete document */
54
+ {"snippet", no_argument, &snippet_flag, 1}, /* snippet only */
55
+ {"output", required_argument, 0, 'o'}, /* which output format to use */
56
+ {"notes", no_argument, &notes_flag, 1}, /* use footnotes */
57
+ {"nonotes", no_argument, &no_notes_flag, 1}, /* don't use footnotes */
58
+ {"smart", no_argument, &typography_flag, 1}, /* use smart typography */
59
+ {"nosmart", no_argument, &no_typography_flag, 1}, /* don't use smart typography */
60
+ {"mask", no_argument, &obfuscate_flag, 1}, /* mask email addresses */
61
+ {"nomask", no_argument, &no_obfuscate_flag, 1}, /* don't mask email addresses */
62
+ {"labels", no_argument, &label_flag, 1}, /* generate labels */
63
+ {"nolabels", no_argument, &no_label_flag, 1}, /* don't generate labels */
64
+ {"escaped-line-breaks", no_argument, &escaped_line_breaks_flag, 1}, /* enable escaped line breaks */
65
+ {"compatibility", no_argument, &compatibility_flag, 1}, /* compatibility mode */
66
+ {"process-html", no_argument, &process_html_flag, 1}, /* process Markdown inside HTML */
67
+ {"random", no_argument, &random_footnotes_flag, 1}, /* Use random numbers for footnote links */
68
+ {"accept", no_argument, 0, 'a'}, /* Accept all proposed CriticMarkup changes */
69
+ {"reject", no_argument, 0, 'r'}, /* Reject all proposed CriticMarkup changes */
70
+ {"metadata-keys", no_argument, 0, 'm'}, /* List all metadata keys */
71
+ {"extract", required_argument, 0, 'e'}, /* show value of specified metadata */
72
+ {"version", no_argument, 0, 'v'}, /* display version information */
73
+ {"help", no_argument, 0, 'h'}, /* display usage information */
74
+ {NULL, 0, NULL, 0}
75
+ };
76
+
77
+ GString *inputbuf;
78
+ FILE *input;
79
+ FILE *output;
80
+ int curchar;
81
+ GString *filename = NULL;
82
+
83
+ char *out;
84
+
85
+ /* set up my data for the parser */
86
+ int output_format = 0;
87
+ unsigned long extensions = 0;
88
+ extensions = extensions | EXT_SMART | EXT_NOTES | EXT_OBFUSCATE;
89
+
90
+ /* process options */
91
+ while (1) {
92
+ int option_index = 0;
93
+
94
+ c = getopt_long (argc, argv, "vhco:bfst:me:ar", long_options, &option_index);
95
+
96
+ if (c == -1)
97
+ break;
98
+
99
+ switch (c) {
100
+ case 0: /* handle long_options */
101
+ /* printf ("option %s", long_options[option_index].name);
102
+ if (optarg)
103
+ printf (" with arg %s", optarg);
104
+ printf("\n"); */
105
+ break;
106
+
107
+ case 'b': /* batch */
108
+ batch_flag = 1;
109
+ break;
110
+
111
+ case 'c': /* compatibility */
112
+ compatibility_flag = 1;
113
+ break;
114
+
115
+ case 'o': /* output filename */
116
+ if (optarg)
117
+ filename = g_string_new(optarg);
118
+ break;
119
+
120
+ case 'v': /* show version */
121
+ printf("\nMultiMarkdown version %s\n%s\n",MMD_VERSION, MMD_COPYRIGHT);
122
+ return(EXIT_SUCCESS);
123
+
124
+ case 'h': /* show usage */
125
+ printf("\nMultiMarkdown version %s\n\n",MMD_VERSION);
126
+ printf(" %s [OPTION...] [FILE...]\n",argv[0]);
127
+ printf("\n"
128
+ " Options:\n"
129
+ " -h, --help Show help\n"
130
+ " -v, --version Show version information\n"
131
+ " -o, --output=FILE Send output to FILE\n"
132
+ " -t, --to=FORMAT Convert to FORMAT\n"
133
+ " -b, --batch Process each file separately\n"
134
+ " -c, --compatibility Markdown compatibility mode\n"
135
+ " -f, --full Force a complete document\n"
136
+ " -s, --snippet Force a snippet\n"
137
+ " --process-html Process Markdown inside of raw HTML\n"
138
+ " -m, --metadata-keys List all metadata keys\n"
139
+ " -e, --extract Extract specified metadata\n"
140
+ " --random Use random numbers for footnote anchors\n"
141
+ "\n"
142
+ " -a, --accept Accept all CriticMarkup changes\n"
143
+ " -r, --reject Reject all CriticMarkup changes\n"
144
+ "\n"
145
+ " --smart, --nosmart Toggle smart typography\n"
146
+ " --notes, --nonotes Toggle footnotes\n"
147
+ " --labels, --nolabels Disable id attributes for headers\n"
148
+ " --mask, --nomask Mask email addresses in HTML\n"
149
+ " --escaped-line-breaks Enable escaped line breaks\n"
150
+
151
+ "\nAvailable FORMATs: html(default), latex, beamer, memoir, odf, opml, lyx\n\n"
152
+ "NOTE: The lyx output format was created by Charles R. Cowan, and \n\tis provided as is.\n\n\n"
153
+ );
154
+ return(EXIT_SUCCESS);
155
+
156
+ case 't': /* output format */
157
+ if (strcmp(optarg, "text") == 0)
158
+ output_format = TEXT_FORMAT;
159
+ else if (strcmp(optarg, "html") == 0)
160
+ output_format = HTML_FORMAT;
161
+ else if (strcmp(optarg, "latex") == 0)
162
+ output_format = LATEX_FORMAT;
163
+ else if (strcmp(optarg, "memoir") == 0)
164
+ output_format = MEMOIR_FORMAT;
165
+ else if (strcmp(optarg, "beamer") == 0)
166
+ output_format = BEAMER_FORMAT;
167
+ else if (strcmp(optarg, "opml") == 0)
168
+ output_format = OPML_FORMAT;
169
+ else if (strcmp(optarg, "odf") == 0)
170
+ output_format = ODF_FORMAT;
171
+ else if (strcmp(optarg, "rtf") == 0)
172
+ output_format = RTF_FORMAT;
173
+ else if (strcmp(optarg, "lyx") == 0)
174
+ output_format = LYX_FORMAT;
175
+ else {
176
+ /* no valid format specified */
177
+ fprintf(stderr, "%s: Unknown output format '%s'\n",argv[0], optarg);
178
+ exit(EXIT_FAILURE);
179
+ }
180
+ break;
181
+
182
+ case 'f': /* full doc */
183
+ extensions = extensions | EXT_COMPLETE;
184
+ break;
185
+
186
+ case 's': /* snippet only */
187
+ extensions = extensions | EXT_SNIPPET;
188
+ break;
189
+
190
+ case 'm': /* list metadata */
191
+ list_meta_keys = 1;
192
+ break;
193
+
194
+ case 'e': /* extract metadata */
195
+ target_meta_key = strdup(optarg);
196
+ break;
197
+
198
+ case '?': /* long handles */
199
+ break;
200
+
201
+ case 'a': /* Accept CriticMarkup changes */
202
+ extensions = extensions | EXT_CRITIC_ACCEPT;
203
+ break;
204
+
205
+ case 'r': /* Reject CriticMarkup changes */
206
+ extensions = extensions | EXT_CRITIC_REJECT;
207
+ break;
208
+
209
+ default:
210
+ fprintf(stderr,"Error parsing options.\n");
211
+ abort();
212
+ }
213
+ }
214
+
215
+ /* Compatibility mode emulates the behavior of Markdown.pl */
216
+ if (compatibility_flag) {
217
+ extensions = 0x000000;
218
+ extensions = extensions | EXT_COMPATIBILITY | EXT_NO_LABELS | EXT_OBFUSCATE;
219
+ }
220
+
221
+ /* apply extensions from long options*/
222
+ if (complete_flag)
223
+ extensions = extensions | EXT_COMPLETE;
224
+
225
+ if (snippet_flag)
226
+ extensions = extensions | EXT_SNIPPET;
227
+
228
+ if (notes_flag)
229
+ extensions = extensions | EXT_NOTES;
230
+
231
+ if (no_notes_flag)
232
+ extensions &= ~EXT_NOTES;
233
+
234
+ if (typography_flag)
235
+ extensions = extensions | EXT_SMART;
236
+
237
+ if (no_typography_flag)
238
+ extensions &= ~EXT_SMART;
239
+
240
+ if (label_flag)
241
+ extensions &= ~EXT_NO_LABELS;
242
+
243
+ if (no_label_flag)
244
+ extensions = extensions | EXT_NO_LABELS;
245
+
246
+ if (obfuscate_flag)
247
+ extensions = extensions | EXT_OBFUSCATE;
248
+
249
+ if (no_obfuscate_flag)
250
+ extensions &= ~EXT_OBFUSCATE;
251
+
252
+ if (process_html_flag)
253
+ extensions = extensions | EXT_PROCESS_HTML;
254
+
255
+ if (random_footnotes_flag)
256
+ extensions = extensions | EXT_RANDOM_FOOT;
257
+
258
+ if (escaped_line_breaks_flag)
259
+ extensions = extensions | EXT_ESCAPED_LINE_BREAKS;
260
+
261
+ /* Enable HEADINGSECTION for certain formats */
262
+ if ((output_format == OPML_FORMAT) || (output_format == BEAMER_FORMAT) || (output_format == LYX_FORMAT))
263
+ extensions = extensions | EXT_HEADINGSECTION;
264
+
265
+ /* fix numbering to account for options */
266
+ argc -= optind;
267
+ argv += optind;
268
+
269
+ /* We expect argc and argv to still point just one below the start of remaining args */
270
+ argc++;
271
+ argv--;
272
+
273
+ /* any filenames */
274
+ numargs = argc -1;
275
+
276
+ if (batch_flag && (numargs != 0)) {
277
+ /* we have multiple file names -- handle individually */
278
+
279
+ for (i = 0; i < numargs; i++) {
280
+ inputbuf = g_string_new("");
281
+ char *temp = NULL;
282
+ char *folder = NULL;
283
+
284
+ /* Read file */
285
+ if ((input = fopen(argv[i+1], "r")) == NULL ) {
286
+ perror(argv[i+1]);
287
+ g_string_free(inputbuf, true);
288
+ g_string_free(filename, true);
289
+ exit(EXIT_FAILURE);
290
+ }
291
+
292
+ while ((curchar = fgetc(input)) != EOF)
293
+ g_string_append_c(inputbuf, curchar);
294
+ fclose(input);
295
+
296
+ /* list metadata keys */
297
+ if (list_meta_keys) {
298
+ out = extract_metadata_keys(inputbuf->str, extensions);
299
+ if (out != NULL) {
300
+ fprintf(stdout, "%s", out);
301
+ free(out);
302
+ g_string_free(inputbuf, true);
303
+ free(target_meta_key);
304
+ return(EXIT_SUCCESS);
305
+ }
306
+ }
307
+
308
+ /* extract metadata */
309
+ if (target_meta_key) {
310
+ out = extract_metadata_value(inputbuf->str, extensions, target_meta_key);
311
+ if (out != NULL)
312
+ fprintf(stdout, "%s\n", out);
313
+ free(out);
314
+ g_string_free(inputbuf, true);
315
+ free(target_meta_key);
316
+ return(EXIT_SUCCESS);
317
+ }
318
+
319
+ if (!(extensions & EXT_COMPATIBILITY)) {
320
+ temp = strdup(argv[i+1]);
321
+ folder = dirname(temp);
322
+ transclude_source(inputbuf, folder, NULL, output_format);
323
+ free(temp);
324
+ // free(folder);
325
+ }
326
+
327
+ out = markdown_to_string(inputbuf->str, extensions, output_format);
328
+
329
+ g_string_free(inputbuf, true);
330
+
331
+ /* set up for output */
332
+ temp = argv[i+1]; /* get current filename */
333
+ if (strrchr(temp,'.') != NULL) {
334
+ long count = strrchr(temp,'.') - temp;
335
+ if (count != 0) {
336
+ /* truncate string at "." */
337
+ temp[count] = '\0';
338
+ }
339
+ }
340
+
341
+ filename = g_string_new(temp);
342
+
343
+ if (output_format == TEXT_FORMAT) {
344
+ g_string_append(filename,".txt");
345
+ } else if (output_format == HTML_FORMAT) {
346
+ g_string_append(filename,".html");
347
+ } else if (output_format == LATEX_FORMAT) {
348
+ g_string_append(filename,".tex");
349
+ } else if (output_format == BEAMER_FORMAT) {
350
+ g_string_append(filename,".tex");
351
+ } else if (output_format == MEMOIR_FORMAT) {
352
+ g_string_append(filename,".tex");
353
+ } else if (output_format == ODF_FORMAT) {
354
+ g_string_append(filename,".fodt");
355
+ } else if (output_format == OPML_FORMAT) {
356
+ g_string_append(filename,".opml");
357
+ } else if (output_format == LYX_FORMAT) {
358
+ g_string_append(filename,".lyx");
359
+ } else if (output_format == RTF_FORMAT) {
360
+ g_string_append(filename,".rtf");
361
+ } else {
362
+ /* default extension -- in this case we only have 1 */
363
+ g_string_append(filename,".txt");
364
+ }
365
+
366
+ if (!(output = fopen(filename->str, "w"))) {
367
+ perror(filename->str);
368
+ } else {
369
+ fprintf(output, "%s\n",out);
370
+ fclose(output);
371
+ }
372
+
373
+ g_string_free(filename,true);
374
+
375
+ if (out != NULL)
376
+ free(out);
377
+ }
378
+ } else {
379
+ /* get input from stdin or concat all files */
380
+ inputbuf = g_string_new("");
381
+ char *folder = NULL;
382
+ char *temp = NULL;
383
+
384
+ folder = getcwd(0,0);
385
+
386
+ if (numargs == 0) {
387
+ /* get stdin */
388
+ while ((curchar = fgetc(stdin)) != EOF)
389
+ g_string_append_c(inputbuf, curchar);
390
+ fclose(stdin);
391
+ } else {
392
+ /* get files */
393
+ free(folder);
394
+ temp = strdup(argv[1]);
395
+ folder = dirname(temp);
396
+
397
+ for (i = 0; i < numargs; i++) {
398
+ if ((input = fopen(argv[i+1], "r")) == NULL ) {
399
+ perror(argv[i+1]);
400
+ g_string_free(inputbuf, true);
401
+ g_string_free(filename, true);
402
+ // free(folder);
403
+ free(temp);
404
+ exit(EXIT_FAILURE);
405
+ }
406
+
407
+ while ((curchar = fgetc(input)) != EOF)
408
+ g_string_append_c(inputbuf, curchar);
409
+ fclose(input);
410
+ }
411
+ }
412
+
413
+ if (!(extensions & EXT_COMPATIBILITY))
414
+ transclude_source(inputbuf, folder, NULL, output_format);
415
+
416
+ free(temp);
417
+
418
+ //if (folder != NULL)
419
+ // free(folder);
420
+
421
+ /* list metadata keys */
422
+ if (list_meta_keys) {
423
+ out = extract_metadata_keys(inputbuf->str, extensions);
424
+ if (out != NULL) {
425
+ fprintf(stdout, "%s", out);
426
+ free(out);
427
+ g_string_free(inputbuf, true);
428
+ free(target_meta_key);
429
+ return(EXIT_SUCCESS);
430
+ }
431
+ }
432
+
433
+ /* extract metadata */
434
+ if (target_meta_key) {
435
+ out = extract_metadata_value(inputbuf->str, extensions, target_meta_key);
436
+ if (out != NULL)
437
+ fprintf(stdout, "%s\n", out);
438
+ free(out);
439
+ g_string_free(inputbuf, true);
440
+ free(target_meta_key);
441
+ return(EXIT_SUCCESS);
442
+ }
443
+
444
+ out = markdown_to_string(inputbuf->str, extensions, output_format);
445
+
446
+ g_string_free(inputbuf, true);
447
+
448
+ /* did we specify an output filename; "-" equals stdout */
449
+ if ((filename == NULL) || (strcmp(filename->str, "-") == 0)) {
450
+ output = stdout;
451
+ } else if (!(output = fopen(filename->str, "w"))) {
452
+ perror(filename->str);
453
+ if (out != NULL)
454
+ free(out);
455
+ g_string_free(filename, true);
456
+ return 1;
457
+ }
458
+
459
+ fprintf(output, "%s\n",out);
460
+ fclose(output);
461
+
462
+ g_string_free(filename, true);
463
+
464
+ if (out != NULL)
465
+ free(out);
466
+ }
467
+
468
+ return(EXIT_SUCCESS);
469
+ }