multimarkdown 4.5.0.r1

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 +1060 -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 +156 -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 +483 -0
  21. data/MultiMarkdown-4/odf.c +1201 -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 +15582 -0
  27. data/MultiMarkdown-4/parser.h +186 -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 +213 -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 +70 -0
  40. data/Rakefile +85 -0
  41. data/bin/ruby_multi_markdown +128 -0
  42. data/ext/extconf.h +3 -0
  43. data/ext/extconf.rb +17 -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/multimarkdown.rb +1 -0
  49. data/multi_markdown.gemspec +37 -0
  50. data/test/multi_markdown_test.rb +64 -0
  51. metadata +119 -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,483 @@
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 obfuscate_flag = 0;
43
+ static int no_obfuscate_flag = 0;
44
+ static int process_html_flag = 0;
45
+ static int random_footnotes_flag = 0;
46
+ bool list_meta_keys = 0;
47
+ char *target_meta_key = FALSE;
48
+
49
+ static struct option long_options[] = {
50
+ {"batch", no_argument, &batch_flag, 1}, /* process each file separately */
51
+ {"to", required_argument, 0, 't'}, /* which output format to use */
52
+ {"full", no_argument, &complete_flag, 1}, /* complete document */
53
+ {"snippet", no_argument, &snippet_flag, 1}, /* snippet only */
54
+ {"output", required_argument, 0, 'o'}, /* which output format to use */
55
+ {"notes", no_argument, &notes_flag, 1}, /* use footnotes */
56
+ {"nonotes", no_argument, &no_notes_flag, 1}, /* don't use footnotes */
57
+ {"smart", no_argument, &typography_flag, 1}, /* use smart typography */
58
+ {"nosmart", no_argument, &no_typography_flag, 1}, /* don't use smart typography */
59
+ {"mask", no_argument, &obfuscate_flag, 1}, /* mask email addresses */
60
+ {"nomask", no_argument, &no_obfuscate_flag, 1}, /* don't mask email addresses */
61
+ {"labels", no_argument, &label_flag, 1}, /* generate labels */
62
+ {"nolabels", no_argument, &no_label_flag, 1}, /* don't generate labels */
63
+ {"compatibility", no_argument, &compatibility_flag, 1}, /* compatibility mode */
64
+ {"process-html", no_argument, &process_html_flag, 1}, /* process Markdown inside HTML */
65
+ {"random", no_argument, &random_footnotes_flag, 1}, /* Use random numbers for footnote links */
66
+ {"accept", no_argument, 0, 'a'}, /* Accept all proposed CriticMarkup changes */
67
+ {"reject", no_argument, 0, 'r'}, /* Reject all proposed CriticMarkup changes */
68
+ {"metadata-keys", no_argument, 0, 'm'}, /* List all metadata keys */
69
+ {"extract", required_argument, 0, 'e'}, /* show value of specified metadata */
70
+ {"version", no_argument, 0, 'v'}, /* display version information */
71
+ {"help", no_argument, 0, 'h'}, /* display usage information */
72
+ {NULL, 0, NULL, 0}
73
+ };
74
+
75
+ GString *inputbuf;
76
+ FILE *input;
77
+ FILE *output;
78
+ int curchar;
79
+ GString *filename = NULL;
80
+
81
+ char *out;
82
+
83
+ /* set up my data for the parser */
84
+ int output_format = 0;
85
+ unsigned long extensions = 0;
86
+ extensions = extensions | EXT_SMART | EXT_NOTES | EXT_OBFUSCATE;
87
+
88
+ /* process options */
89
+ while (1) {
90
+ int option_index = 0;
91
+
92
+ c = getopt_long (argc, argv, "vhco:bfst:me:ar", long_options, &option_index);
93
+
94
+ if (c == -1)
95
+ break;
96
+
97
+ switch (c) {
98
+ case 0: /* handle long_options */
99
+ /* printf ("option %s", long_options[option_index].name);
100
+ if (optarg)
101
+ printf (" with arg %s", optarg);
102
+ printf("\n"); */
103
+ break;
104
+
105
+ case 'b': /* batch */
106
+ batch_flag = 1;
107
+ break;
108
+
109
+ case 'c': /* compatibility */
110
+ compatibility_flag = 1;
111
+ break;
112
+
113
+ case 'o': /* output filename */
114
+ if (optarg)
115
+ filename = g_string_new(optarg);
116
+ break;
117
+
118
+ case 'v': /* show version */
119
+ printf("\nMultiMarkdown version %s\n%s\n",MMD_VERSION, MMD_COPYRIGHT);
120
+ return(EXIT_SUCCESS);
121
+
122
+ case 'h': /* show usage */
123
+ printf("\nMultiMarkdown version %s\n\n",MMD_VERSION);
124
+ printf(" %s [OPTION...] [FILE...]\n",argv[0]);
125
+ printf("\n"
126
+ " Options:\n"
127
+ " -h, --help Show help\n"
128
+ " -v, --version Show version information\n"
129
+ " -o, --output=FILE Send output to FILE\n"
130
+ " -t, --to=FORMAT Convert to FORMAT\n"
131
+ " -b, --batch Process each file separately\n"
132
+ " -c, --compatibility Markdown compatibility mode\n"
133
+ " -f, --full Force a complete document\n"
134
+ " -s, --snippet Force a snippet\n"
135
+ " --process-html Process Markdown inside of raw HTML\n"
136
+ " -m, --metadata-keys List all metadata keys\n"
137
+ " -e, --extract Extract specified metadata\n"
138
+ " --random Use random numbers for footnote anchors\n"
139
+ "\n"
140
+ " -a, --accept Accept all CriticMarkup changes\n"
141
+ " -r, --reject Reject all CriticMarkup changes\n"
142
+ "\n"
143
+ " --smart, --nosmart Toggle smart typography\n"
144
+ " --notes, --nonotes Toggle footnotes\n"
145
+ " --labels, --nolabels Disable id attributes for headers\n"
146
+ " --mask, --nomask Mask email addresses in HTML\n"
147
+
148
+ "\nAvailable FORMATs: html(default), latex, beamer, memoir, odf, opml, lyx\n\n"
149
+ "NOTE: The lyx output format was created by Charles R. Cowan, and \n\tis provided as is.\n\n\n"
150
+ );
151
+ return(EXIT_SUCCESS);
152
+
153
+ case 't': /* output format */
154
+ if (strcmp(optarg, "text") == 0)
155
+ output_format = TEXT_FORMAT;
156
+ else if (strcmp(optarg, "html") == 0)
157
+ output_format = HTML_FORMAT;
158
+ else if (strcmp(optarg, "latex") == 0)
159
+ output_format = LATEX_FORMAT;
160
+ else if (strcmp(optarg, "memoir") == 0)
161
+ output_format = MEMOIR_FORMAT;
162
+ else if (strcmp(optarg, "beamer") == 0)
163
+ output_format = BEAMER_FORMAT;
164
+ else if (strcmp(optarg, "opml") == 0)
165
+ output_format = OPML_FORMAT;
166
+ else if (strcmp(optarg, "odf") == 0)
167
+ output_format = ODF_FORMAT;
168
+ else if (strcmp(optarg, "rtf") == 0)
169
+ output_format = RTF_FORMAT;
170
+ else if (strcmp(optarg, "lyx") == 0)
171
+ output_format = LYX_FORMAT;
172
+ else {
173
+ /* no valid format specified */
174
+ fprintf(stderr, "%s: Unknown output format '%s'\n",argv[0], optarg);
175
+ exit(EXIT_FAILURE);
176
+ }
177
+ break;
178
+
179
+ case 'f': /* full doc */
180
+ extensions = extensions | EXT_COMPLETE;
181
+ break;
182
+
183
+ case 's': /* snippet only */
184
+ extensions = extensions | EXT_SNIPPET;
185
+ break;
186
+
187
+ case 'm': /* list metadata */
188
+ list_meta_keys = 1;
189
+ break;
190
+
191
+ case 'e': /* extract metadata */
192
+ target_meta_key = strdup(optarg);
193
+ break;
194
+
195
+ case '?': /* long handles */
196
+ break;
197
+
198
+ case 'a': /* Accept CriticMarkup changes */
199
+ extensions = extensions | EXT_CRITIC_ACCEPT;
200
+ break;
201
+
202
+ case 'r': /* Reject CriticMarkup changes */
203
+ extensions = extensions | EXT_CRITIC_REJECT;
204
+ break;
205
+
206
+ default:
207
+ fprintf(stderr,"Error parsing options.\n");
208
+ abort();
209
+ }
210
+ }
211
+
212
+ /* Compatibility mode emulates the behavior of Markdown.pl */
213
+ if (compatibility_flag) {
214
+ extensions = 0x000000;
215
+ extensions = extensions | EXT_COMPATIBILITY | EXT_NO_LABELS | EXT_OBFUSCATE;
216
+ }
217
+
218
+ /* apply extensions from long options*/
219
+ if (complete_flag)
220
+ extensions = extensions | EXT_COMPLETE;
221
+
222
+ if (snippet_flag)
223
+ extensions = extensions | EXT_SNIPPET;
224
+
225
+ if (notes_flag)
226
+ extensions = extensions | EXT_NOTES;
227
+
228
+ if (no_notes_flag)
229
+ extensions &= ~EXT_NOTES;
230
+
231
+ if (typography_flag)
232
+ extensions = extensions | EXT_SMART;
233
+
234
+ if (no_typography_flag)
235
+ extensions &= ~EXT_SMART;
236
+
237
+ if (label_flag)
238
+ extensions &= ~EXT_NO_LABELS;
239
+
240
+ if (no_label_flag)
241
+ extensions = extensions | EXT_NO_LABELS;
242
+
243
+ if (obfuscate_flag)
244
+ extensions = extensions | EXT_OBFUSCATE;
245
+
246
+ if (no_obfuscate_flag)
247
+ extensions &= ~EXT_OBFUSCATE;
248
+
249
+ if (process_html_flag)
250
+ extensions = extensions | EXT_PROCESS_HTML;
251
+
252
+ if (random_footnotes_flag)
253
+ extensions = extensions | EXT_RANDOM_FOOT;
254
+
255
+ /* Enable HEADINGSECTION for certain formats */
256
+ if ((output_format == OPML_FORMAT) || (output_format == BEAMER_FORMAT) || (output_format == LYX_FORMAT))
257
+ extensions = extensions | EXT_HEADINGSECTION;
258
+
259
+ /* fix numbering to account for options */
260
+ argc -= optind;
261
+ argv += optind;
262
+
263
+ /* We expect argc and argv to still point just one below the start of remaining args */
264
+ argc++;
265
+ argv--;
266
+
267
+ /* any filenames */
268
+ numargs = argc -1;
269
+
270
+ if (batch_flag && (numargs != 0)) {
271
+ /* we have multiple file names -- handle individually */
272
+
273
+ for (i = 0; i < numargs; i++) {
274
+ inputbuf = g_string_new("");
275
+ char *temp = NULL;
276
+ char *folder = NULL;
277
+
278
+ /* Read file */
279
+ if ((input = fopen(argv[i+1], "r")) == NULL ) {
280
+ perror(argv[i+1]);
281
+ g_string_free(inputbuf, true);
282
+ g_string_free(filename, true);
283
+ exit(EXIT_FAILURE);
284
+ }
285
+
286
+ while ((curchar = fgetc(input)) != EOF)
287
+ g_string_append_c(inputbuf, curchar);
288
+ fclose(input);
289
+
290
+ /* list metadata keys */
291
+ if (list_meta_keys) {
292
+ out = extract_metadata_keys(inputbuf->str, extensions);
293
+ if (out != NULL) {
294
+ fprintf(stdout, "%s", out);
295
+ free(out);
296
+ g_string_free(inputbuf, true);
297
+ free(target_meta_key);
298
+ return(EXIT_SUCCESS);
299
+ }
300
+ }
301
+
302
+ /* extract metadata */
303
+ if (target_meta_key) {
304
+ out = extract_metadata_value(inputbuf->str, extensions, target_meta_key);
305
+ if (out != NULL)
306
+ fprintf(stdout, "%s\n", out);
307
+ free(out);
308
+ g_string_free(inputbuf, true);
309
+ free(target_meta_key);
310
+ return(EXIT_SUCCESS);
311
+ }
312
+
313
+ if (!(extensions & EXT_COMPATIBILITY)) {
314
+ temp = strdup(argv[i+1]);
315
+ folder = dirname(temp);
316
+ transclude_source(inputbuf, folder, NULL, output_format);
317
+ free(temp);
318
+ // free(folder);
319
+ }
320
+
321
+ target_meta_key = extract_metadata_value(inputbuf->str, extensions, "latexmode");
322
+ if (target_meta_key != NULL) {
323
+ temp = label_from_string(target_meta_key);
324
+ if (strcmp(temp, "beamer") == 0) {
325
+ extensions = extensions | EXT_HEADINGSECTION;
326
+ }
327
+ free(temp);
328
+ }
329
+ free(target_meta_key);
330
+
331
+ out = markdown_to_string(inputbuf->str, extensions, output_format);
332
+
333
+ g_string_free(inputbuf, true);
334
+
335
+ /* set up for output */
336
+ temp = argv[i+1]; /* get current filename */
337
+ if (strrchr(temp,'.') != NULL) {
338
+ long count = strrchr(temp,'.') - temp;
339
+ if (count != 0) {
340
+ /* truncate string at "." */
341
+ temp[count] = '\0';
342
+ }
343
+ }
344
+
345
+ filename = g_string_new(temp);
346
+
347
+ if (output_format == TEXT_FORMAT) {
348
+ g_string_append(filename,".txt");
349
+ } else if (output_format == HTML_FORMAT) {
350
+ g_string_append(filename,".html");
351
+ } else if (output_format == LATEX_FORMAT) {
352
+ g_string_append(filename,".tex");
353
+ } else if (output_format == BEAMER_FORMAT) {
354
+ g_string_append(filename,".tex");
355
+ } else if (output_format == MEMOIR_FORMAT) {
356
+ g_string_append(filename,".tex");
357
+ } else if (output_format == ODF_FORMAT) {
358
+ g_string_append(filename,".fodt");
359
+ } else if (output_format == OPML_FORMAT) {
360
+ g_string_append(filename,".opml");
361
+ } else if (output_format == LYX_FORMAT) {
362
+ g_string_append(filename,".lyx");
363
+ } else if (output_format == RTF_FORMAT) {
364
+ g_string_append(filename,".rtf");
365
+ } else {
366
+ /* default extension -- in this case we only have 1 */
367
+ g_string_append(filename,".txt");
368
+ }
369
+
370
+ if (!(output = fopen(filename->str, "w"))) {
371
+ perror(filename->str);
372
+ } else {
373
+ fprintf(output, "%s\n",out);
374
+ fclose(output);
375
+ }
376
+
377
+ g_string_free(filename,true);
378
+
379
+ if (out != NULL)
380
+ free(out);
381
+ }
382
+ } else {
383
+ /* get input from stdin or concat all files */
384
+ inputbuf = g_string_new("");
385
+ char *folder = NULL;
386
+ char *temp = NULL;
387
+
388
+ folder = getcwd(0,0);
389
+
390
+ if (numargs == 0) {
391
+ /* get stdin */
392
+ while ((curchar = fgetc(stdin)) != EOF)
393
+ g_string_append_c(inputbuf, curchar);
394
+ fclose(stdin);
395
+ } else {
396
+ /* get files */
397
+ free(folder);
398
+ temp = strdup(argv[1]);
399
+ folder = dirname(temp);
400
+
401
+ for (i = 0; i < numargs; i++) {
402
+ if ((input = fopen(argv[i+1], "r")) == NULL ) {
403
+ perror(argv[i+1]);
404
+ g_string_free(inputbuf, true);
405
+ g_string_free(filename, true);
406
+ free(folder);
407
+ free(temp);
408
+ exit(EXIT_FAILURE);
409
+ }
410
+
411
+ while ((curchar = fgetc(input)) != EOF)
412
+ g_string_append_c(inputbuf, curchar);
413
+ fclose(input);
414
+ }
415
+ }
416
+
417
+ if (!(extensions & EXT_COMPATIBILITY))
418
+ transclude_source(inputbuf, folder, NULL, output_format);
419
+
420
+ free(temp);
421
+
422
+ //if (folder != NULL)
423
+ // free(folder);
424
+
425
+ /* list metadata keys */
426
+ if (list_meta_keys) {
427
+ out = extract_metadata_keys(inputbuf->str, extensions);
428
+ if (out != NULL) {
429
+ fprintf(stdout, "%s", out);
430
+ free(out);
431
+ g_string_free(inputbuf, true);
432
+ free(target_meta_key);
433
+ return(EXIT_SUCCESS);
434
+ }
435
+ }
436
+
437
+ /* extract metadata */
438
+ if (target_meta_key) {
439
+ out = extract_metadata_value(inputbuf->str, extensions, target_meta_key);
440
+ if (out != NULL)
441
+ fprintf(stdout, "%s\n", out);
442
+ free(out);
443
+ g_string_free(inputbuf, true);
444
+ free(target_meta_key);
445
+ return(EXIT_SUCCESS);
446
+ }
447
+
448
+ target_meta_key = extract_metadata_value(inputbuf->str, extensions, "latexmode");
449
+ if (target_meta_key != NULL) {
450
+ temp = label_from_string(target_meta_key);
451
+ if (strcmp(temp, "beamer") == 0) {
452
+ extensions = extensions | EXT_HEADINGSECTION;
453
+ }
454
+ free(temp);
455
+ }
456
+ free(target_meta_key);
457
+
458
+ out = markdown_to_string(inputbuf->str, extensions, output_format);
459
+
460
+ g_string_free(inputbuf, true);
461
+
462
+ /* did we specify an output filename; "-" equals stdout */
463
+ if ((filename == NULL) || (strcmp(filename->str, "-") == 0)) {
464
+ output = stdout;
465
+ } else if (!(output = fopen(filename->str, "w"))) {
466
+ perror(filename->str);
467
+ if (out != NULL)
468
+ free(out);
469
+ g_string_free(filename, true);
470
+ return 1;
471
+ }
472
+
473
+ fprintf(output, "%s\n",out);
474
+ fclose(output);
475
+
476
+ g_string_free(filename, true);
477
+
478
+ if (out != NULL)
479
+ free(out);
480
+ }
481
+
482
+ return(EXIT_SUCCESS);
483
+ }