rmultimarkdown 6.4.0.4 → 6.7.0.0
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.
- checksums.yaml +5 -5
- data/Rakefile +7 -13
- data/ext/Makefile +67 -55
- data/ext/extconf.rb +7 -5
- data/ext/mmd/aho-corasick.c +8 -8
- data/ext/mmd/aho-corasick.h +3 -3
- data/ext/mmd/argtable3.c +6537 -0
- data/ext/mmd/argtable3.h +273 -0
- data/ext/mmd/beamer.c +12 -1
- data/ext/mmd/char.c +120 -27
- data/ext/mmd/char.h +23 -23
- data/ext/mmd/critic_markup.c +7 -6
- data/ext/mmd/d_string.c +88 -32
- data/ext/mmd/{include/d_string.h → d_string.h} +50 -38
- data/ext/mmd/epub.c +36 -12
- data/ext/mmd/epub.h +2 -2
- data/ext/mmd/file.c +50 -40
- data/ext/mmd/file.h +2 -2
- data/ext/mmd/html.c +164 -99
- data/ext/mmd/html.h +3 -2
- data/ext/mmd/i18n.h +15 -11
- data/ext/mmd/itmz-lexer.c +16978 -0
- data/ext/mmd/itmz-lexer.h +132 -0
- data/ext/mmd/itmz-parser.c +1189 -0
- data/ext/mmd/itmz-parser.h +11 -0
- data/ext/mmd/itmz-reader.c +388 -0
- data/ext/mmd/itmz-reader.h +111 -0
- data/ext/mmd/itmz.c +567 -0
- data/ext/mmd/itmz.h +117 -0
- data/ext/mmd/latex.c +93 -41
- data/ext/mmd/lexer.c +3506 -2774
- data/ext/mmd/{include/libMultiMarkdown.h → libMultiMarkdown.h} +49 -2
- data/ext/mmd/main.c +612 -0
- data/ext/mmd/memoir.c +4 -1
- data/ext/mmd/miniz.c +6905 -6680
- data/ext/mmd/miniz.h +456 -476
- data/ext/mmd/mmd.c +399 -94
- data/ext/mmd/mmd.h +25 -25
- data/ext/mmd/object_pool.h +3 -3
- data/ext/mmd/opendocument-content.c +137 -69
- data/ext/mmd/opendocument-content.h +2 -2
- data/ext/mmd/opendocument.c +35 -14
- data/ext/mmd/opendocument.h +2 -2
- data/ext/mmd/opml-lexer.c +259 -637
- data/ext/mmd/opml-lexer.h +1 -17
- data/ext/mmd/opml-parser.c +194 -188
- data/ext/mmd/opml-reader.c +72 -142
- data/ext/mmd/opml-reader.h +1 -1
- data/ext/mmd/opml.c +13 -13
- data/ext/mmd/opml.h +1 -1
- data/ext/mmd/parser.c +1623 -1244
- data/ext/mmd/rng.c +8 -3
- data/ext/mmd/scanners.c +66625 -103198
- data/ext/mmd/scanners.h +1 -0
- data/ext/mmd/stack.c +62 -20
- data/ext/mmd/stack.h +10 -21
- data/ext/mmd/textbundle.c +23 -7
- data/ext/mmd/textbundle.h +2 -2
- data/ext/mmd/token.c +42 -16
- data/ext/mmd/{include/token.h → token.h} +22 -8
- data/ext/mmd/token_pairs.c +0 -16
- data/ext/mmd/transclude.c +6 -2
- data/ext/mmd/uthash.h +745 -745
- data/ext/mmd/version.h +8 -8
- data/ext/mmd/writer.c +225 -63
- data/ext/mmd/writer.h +50 -36
- data/ext/mmd/xml.c +855 -0
- data/ext/mmd/xml.h +134 -0
- data/ext/mmd/zip.c +71 -4
- data/ext/mmd/zip.h +7 -1
- data/ext/ruby_multi_markdown.c +9 -18
- data/lib/multi_markdown/version.rb +1 -1
- data/lib/multi_markdown.bundle +0 -0
- data/rmultimarkdown.gemspec +0 -2
- metadata +22 -28
- data/ext/mmd/char_lookup.c +0 -212
data/ext/mmd/main.c
ADDED
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
/**
|
|
2
|
+
|
|
3
|
+
MultiMarkdown 6 -- Lightweight markup processor to produce HTML, LaTeX, and more.
|
|
4
|
+
|
|
5
|
+
@file main.c
|
|
6
|
+
|
|
7
|
+
@brief Create command-line frontend for libMultiMarkdown.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@author Fletcher T. Penney
|
|
11
|
+
@bug
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
**/
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
|
|
18
|
+
Copyright © 2016 - 2017 Fletcher T. Penney.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
The `MultiMarkdown 6` project is released under the MIT License..
|
|
22
|
+
|
|
23
|
+
GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project:
|
|
24
|
+
|
|
25
|
+
https://github.com/fletcher/MultiMarkdown-4/
|
|
26
|
+
|
|
27
|
+
MMD 4 is released under both the MIT License and GPL.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
CuTest is released under the zlib/libpng license. See CuTest.c for the text
|
|
31
|
+
of the license.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## The MIT License ##
|
|
35
|
+
|
|
36
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
37
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
38
|
+
in the Software without restriction, including without limitation the rights
|
|
39
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
40
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
41
|
+
furnished to do so, subject to the following conditions:
|
|
42
|
+
|
|
43
|
+
The above copyright notice and this permission notice shall be included in
|
|
44
|
+
all copies or substantial portions of the Software.
|
|
45
|
+
|
|
46
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
47
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
48
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
49
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
50
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
51
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
52
|
+
THE SOFTWARE.
|
|
53
|
+
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
#include <ctype.h>
|
|
57
|
+
#include <libgen.h>
|
|
58
|
+
#include <limits.h>
|
|
59
|
+
#include <stdio.h>
|
|
60
|
+
#include <stdlib.h>
|
|
61
|
+
#include <string.h>
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
#include "argtable3.h"
|
|
65
|
+
#include "d_string.h"
|
|
66
|
+
#include "file.h"
|
|
67
|
+
#include "i18n.h"
|
|
68
|
+
#include "libMultiMarkdown.h"
|
|
69
|
+
#include "token.h"
|
|
70
|
+
#include "uuid.h"
|
|
71
|
+
#include "version.h"
|
|
72
|
+
#include "zip.h"
|
|
73
|
+
|
|
74
|
+
#define kBUFFERSIZE 4096 // How many bytes to read at a time
|
|
75
|
+
|
|
76
|
+
// argtable structs
|
|
77
|
+
struct arg_lit * a_help, *a_version, *a_compatibility, *a_nolabels, *a_batch,
|
|
78
|
+
*a_accept, *a_reject, *a_full, *a_snippet, *a_random, *a_unique, *a_meta,
|
|
79
|
+
*a_notransclude, *a_nosmart, *a_opml, *a_itmz;
|
|
80
|
+
struct arg_str * a_format, *a_lang, *a_extract;
|
|
81
|
+
struct arg_file * a_file, *a_o;
|
|
82
|
+
struct arg_end * a_end;
|
|
83
|
+
struct arg_rem * a_rem1, *a_rem2, *a_rem3, *a_rem4, *a_rem5, *a_rem6;
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
/// strdup() not available on all platforms
|
|
87
|
+
static char * my_strdup(const char * source) {
|
|
88
|
+
if (source == NULL) {
|
|
89
|
+
return NULL;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
char * result = malloc(strlen(source) + 1);
|
|
93
|
+
|
|
94
|
+
if (result) {
|
|
95
|
+
strcpy(result, source);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
/// Given a filename, remove the extension and replace it with a new one.
|
|
103
|
+
/// The next extension must include the leading '.', e.g. '.html'
|
|
104
|
+
char * filename_with_extension(const char * original, const char * new_extension) {
|
|
105
|
+
char * name_no_ext;
|
|
106
|
+
DString * new_name;
|
|
107
|
+
|
|
108
|
+
// Determine output filename without file extension
|
|
109
|
+
name_no_ext = my_strdup(original);
|
|
110
|
+
|
|
111
|
+
if (strrchr(name_no_ext, '.') != NULL) {
|
|
112
|
+
long count = strrchr(name_no_ext, '.') - name_no_ext;
|
|
113
|
+
|
|
114
|
+
if (count != 0) {
|
|
115
|
+
name_no_ext[count] = '\0';
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
new_name = d_string_new(name_no_ext);
|
|
120
|
+
free(name_no_ext);
|
|
121
|
+
|
|
122
|
+
d_string_append(new_name, new_extension);
|
|
123
|
+
|
|
124
|
+
name_no_ext = new_name->str;
|
|
125
|
+
|
|
126
|
+
d_string_free(new_name, false);
|
|
127
|
+
|
|
128
|
+
return name_no_ext;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
int main(int argc, char ** argv) {
|
|
133
|
+
int exitcode = EXIT_SUCCESS;
|
|
134
|
+
char * binname = "multimarkdown";
|
|
135
|
+
short format = FORMAT_HTML;
|
|
136
|
+
short language = LC_EN;
|
|
137
|
+
|
|
138
|
+
// Initialize argtable structs
|
|
139
|
+
void * argtable[] = {
|
|
140
|
+
a_help = arg_lit0(NULL, "help", "display this help and exit"),
|
|
141
|
+
a_version = arg_lit0(NULL, "version", "display version info and exit"),
|
|
142
|
+
|
|
143
|
+
a_rem1 = arg_rem("", ""),
|
|
144
|
+
|
|
145
|
+
a_batch = arg_lit0("b", "batch", "process each file separately"),
|
|
146
|
+
a_full = arg_lit0("f", "full", "force a complete document"),
|
|
147
|
+
a_snippet = arg_lit0("s", "snippet", "force a snippet"),
|
|
148
|
+
a_compatibility = arg_lit0("c", "compatibility", "Markdown compatibility mode"),
|
|
149
|
+
a_random = arg_lit0(NULL, "random", "use random numbers for footnote anchors"),
|
|
150
|
+
a_unique = arg_lit0(NULL, "unique", "use random numbers for header labels unless manually specified"),
|
|
151
|
+
a_nosmart = arg_lit0(NULL, "nosmart", "Disable smart typography"),
|
|
152
|
+
a_nolabels = arg_lit0(NULL, "nolabels", "Disable id attributes for headers"),
|
|
153
|
+
a_notransclude = arg_lit0(NULL, "notransclude", "Disable file transclusion"),
|
|
154
|
+
a_opml = arg_lit0(NULL, "opml", "Convert OPML source to plain text before processing"),
|
|
155
|
+
a_itmz = arg_lit0(NULL, "itmz", "Convert ITMZ (iThoughts) source to plain text before processing"),
|
|
156
|
+
|
|
157
|
+
a_rem2 = arg_rem("", ""),
|
|
158
|
+
|
|
159
|
+
a_format = arg_str0("t", "to", "FORMAT", "convert to FORMAT, FORMAT = html|latex|beamer|memoir|mmd|odt|fodt|epub|opml|itmz|bundle|bundlezip"),
|
|
160
|
+
a_o = arg_file0("o", "output", "FILE", "send output to FILE"),
|
|
161
|
+
|
|
162
|
+
a_rem3 = arg_rem("", ""),
|
|
163
|
+
|
|
164
|
+
a_accept = arg_lit0("a", "accept", "accept all CriticMarkup changes"),
|
|
165
|
+
a_reject = arg_lit0("r", "reject", "reject all CriticMarkup changes"),
|
|
166
|
+
|
|
167
|
+
a_rem4 = arg_rem("", ""),
|
|
168
|
+
|
|
169
|
+
a_lang = arg_str0("l", "lang", "LANG", "language/smart quote localization, LANG = en|es|de|fr|he|nl|sv"),
|
|
170
|
+
|
|
171
|
+
a_rem5 = arg_rem("", ""),
|
|
172
|
+
|
|
173
|
+
a_meta = arg_lit0("m", "metadata-keys", "list all metadata keys"),
|
|
174
|
+
a_extract = arg_str0("e", "extract", "KEY", "extract specified metadata key"),
|
|
175
|
+
|
|
176
|
+
a_rem6 = arg_rem("", ""),
|
|
177
|
+
|
|
178
|
+
a_file = arg_filen(NULL, NULL, "<FILE>", 0, argc + 2, "read input from file(s) -- use stdin if no files given"),
|
|
179
|
+
|
|
180
|
+
a_end = arg_end(20),
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// Set default options
|
|
184
|
+
a_o->filename[0] = "-"; // Default to stdout if no option specified
|
|
185
|
+
|
|
186
|
+
int nerrors = arg_parse(argc, argv, argtable);
|
|
187
|
+
|
|
188
|
+
// '--help' takes precedence
|
|
189
|
+
if (a_help->count > 0) {
|
|
190
|
+
printf("\n%s v%s -- %s\n\n", LIBMULTIMARKDOWN_NAME, LIBMULTIMARKDOWN_VERSION, LIBMULTIMARKDOWN_COPYRIGHT);
|
|
191
|
+
printf("\tUsage: %s", binname);
|
|
192
|
+
arg_print_syntax(stdout, argtable, "\n\n");
|
|
193
|
+
printf("Options:\n");
|
|
194
|
+
arg_print_glossary(stdout, argtable, "\t%-25s %s\n");
|
|
195
|
+
printf("\n");
|
|
196
|
+
goto exit2;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (nerrors > 0) {
|
|
200
|
+
// Report errors
|
|
201
|
+
arg_print_errors(stdout, a_end, LIBMULTIMARKDOWN_NAME);
|
|
202
|
+
printf("Try '%s --help' for more information.\n", binname);
|
|
203
|
+
exitcode = 1;
|
|
204
|
+
goto exit2;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// '--version' also takes precedence
|
|
208
|
+
if (a_version->count > 0) {
|
|
209
|
+
printf("\nMultiMarkdown 6 v%s\n", LIBMULTIMARKDOWN_VERSION);
|
|
210
|
+
printf("%s\n\n", LIBMULTIMARKDOWN_COPYRIGHT);
|
|
211
|
+
printf("%s\n", LIBMULTIMARKDOWN_LICENSE);
|
|
212
|
+
printf("\n");
|
|
213
|
+
goto exit2;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
// Parse options
|
|
218
|
+
unsigned long extensions = EXT_SMART | EXT_NOTES | EXT_CRITIC | EXT_TRANSCLUDE;
|
|
219
|
+
|
|
220
|
+
if (a_compatibility->count > 0) {
|
|
221
|
+
// Compatibility mode disables certain features
|
|
222
|
+
// Reset extensions
|
|
223
|
+
extensions = EXT_COMPATIBILITY | EXT_NO_LABELS | EXT_OBFUSCATE | EXT_NO_METADATA;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (a_nosmart->count > 0) {
|
|
227
|
+
// Disable smart typography
|
|
228
|
+
extensions &= ~EXT_SMART;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (a_nolabels->count > 0) {
|
|
232
|
+
// Disable header id attributes
|
|
233
|
+
extensions |= EXT_NO_LABELS;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (a_notransclude->count > 0) {
|
|
237
|
+
// Disable file transclusion
|
|
238
|
+
extensions &= ~EXT_TRANSCLUDE;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (a_opml->count > 0) {
|
|
242
|
+
// Attempt to convert from OPML
|
|
243
|
+
extensions |= EXT_PARSE_OPML;
|
|
244
|
+
} else if (a_itmz->count > 0) {
|
|
245
|
+
// Attempt to convert from ITMZ
|
|
246
|
+
extensions |= EXT_PARSE_ITMZ;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (a_accept->count > 0) {
|
|
250
|
+
// Accept CriticMarkup changes
|
|
251
|
+
extensions |= EXT_CRITIC_ACCEPT | EXT_CRITIC;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (a_reject->count > 0) {
|
|
255
|
+
// Reject CriticMarkup changes
|
|
256
|
+
extensions |= EXT_CRITIC_REJECT | EXT_CRITIC;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (a_reject->count && a_accept->count) {
|
|
260
|
+
// Old options that don't apply now, so change them
|
|
261
|
+
extensions &= ~(EXT_CRITIC_REJECT | EXT_CRITIC_ACCEPT);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (a_full->count > 0) {
|
|
265
|
+
// Force complete document
|
|
266
|
+
extensions |= EXT_COMPLETE;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (a_snippet->count > 0) {
|
|
270
|
+
// Force snippet
|
|
271
|
+
extensions |= EXT_SNIPPET;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (a_random->count > 0) {
|
|
275
|
+
// Use random anchors
|
|
276
|
+
extensions |= EXT_RANDOM_FOOT;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (a_unique->count > 0) {
|
|
280
|
+
// Use random header labels
|
|
281
|
+
extensions |= EXT_RANDOM_LABELS;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (a_format->count > 0) {
|
|
285
|
+
if (strcmp(a_format->sval[0], "html") == 0) {
|
|
286
|
+
format = FORMAT_HTML;
|
|
287
|
+
} else if (strcmp(a_format->sval[0], "latex") == 0) {
|
|
288
|
+
format = FORMAT_LATEX;
|
|
289
|
+
} else if (strcmp(a_format->sval[0], "beamer") == 0) {
|
|
290
|
+
format = FORMAT_BEAMER;
|
|
291
|
+
} else if (strcmp(a_format->sval[0], "memoir") == 0) {
|
|
292
|
+
format = FORMAT_MEMOIR;
|
|
293
|
+
} else if (strcmp(a_format->sval[0], "mmd") == 0) {
|
|
294
|
+
format = FORMAT_MMD;
|
|
295
|
+
} else if (strcmp(a_format->sval[0], "odt") == 0) {
|
|
296
|
+
format = FORMAT_ODT;
|
|
297
|
+
} else if (strcmp(a_format->sval[0], "fodt") == 0) {
|
|
298
|
+
format = FORMAT_FODT;
|
|
299
|
+
} else if (strcmp(a_format->sval[0], "epub") == 0) {
|
|
300
|
+
format = FORMAT_EPUB;
|
|
301
|
+
} else if (strcmp(a_format->sval[0], "bundle") == 0) {
|
|
302
|
+
format = FORMAT_TEXTBUNDLE;
|
|
303
|
+
} else if (strcmp(a_format->sval[0], "bundlezip") == 0) {
|
|
304
|
+
format = FORMAT_TEXTBUNDLE_COMPRESSED;
|
|
305
|
+
} else if (strcmp(a_format->sval[0], "opml") == 0) {
|
|
306
|
+
format = FORMAT_OPML;
|
|
307
|
+
} else if (strcmp(a_format->sval[0], "itmz") == 0) {
|
|
308
|
+
format = FORMAT_ITMZ;
|
|
309
|
+
} else {
|
|
310
|
+
// No valid format found
|
|
311
|
+
fprintf(stderr, "%s: Unknown output format '%s'\n", binname, a_format->sval[0]);
|
|
312
|
+
exitcode = 1;
|
|
313
|
+
goto exit2;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (a_lang->count > 0) {
|
|
318
|
+
language = LANG_FROM_STR(a_lang->sval[0]);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Determine input
|
|
322
|
+
if (a_file->count == 0) {
|
|
323
|
+
// Read from stdin
|
|
324
|
+
} else {
|
|
325
|
+
// Read from files
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
DString * buffer = NULL;
|
|
329
|
+
DString * result = NULL;
|
|
330
|
+
char * char_result = NULL;
|
|
331
|
+
FILE * output_stream;
|
|
332
|
+
char * output_filename;
|
|
333
|
+
|
|
334
|
+
// Increment counter and prepare token pool
|
|
335
|
+
#ifdef kUseObjectPool
|
|
336
|
+
token_pool_init();
|
|
337
|
+
#endif
|
|
338
|
+
|
|
339
|
+
// Seed random numbers
|
|
340
|
+
custom_seed_rand();
|
|
341
|
+
|
|
342
|
+
// Determine processing mode -- batch/stdin/files??
|
|
343
|
+
|
|
344
|
+
if ((a_batch->count) && (a_file->count)) {
|
|
345
|
+
// Batch process 1 or more files
|
|
346
|
+
for (int i = 0; i < a_file->count; ++i) {
|
|
347
|
+
|
|
348
|
+
buffer = scan_file(a_file->filename[i]);
|
|
349
|
+
|
|
350
|
+
if (buffer == NULL) {
|
|
351
|
+
fprintf(stderr, "Error reading file '%s'\n", a_file->filename[i]);
|
|
352
|
+
exitcode = 1;
|
|
353
|
+
goto exit2;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Append output file extension
|
|
357
|
+
switch (format) {
|
|
358
|
+
case FORMAT_HTML:
|
|
359
|
+
output_filename = filename_with_extension(a_file->filename[i], ".html");
|
|
360
|
+
break;
|
|
361
|
+
|
|
362
|
+
case FORMAT_LATEX:
|
|
363
|
+
case FORMAT_BEAMER:
|
|
364
|
+
case FORMAT_MEMOIR:
|
|
365
|
+
output_filename = filename_with_extension(a_file->filename[i], ".tex");
|
|
366
|
+
break;
|
|
367
|
+
|
|
368
|
+
case FORMAT_FODT:
|
|
369
|
+
output_filename = filename_with_extension(a_file->filename[i], ".fodt");
|
|
370
|
+
break;
|
|
371
|
+
|
|
372
|
+
case FORMAT_ODT:
|
|
373
|
+
output_filename = filename_with_extension(a_file->filename[i], ".odt");
|
|
374
|
+
break;
|
|
375
|
+
|
|
376
|
+
case FORMAT_MMD:
|
|
377
|
+
output_filename = filename_with_extension(a_file->filename[i], ".mmdtext");
|
|
378
|
+
break;
|
|
379
|
+
|
|
380
|
+
case FORMAT_EPUB:
|
|
381
|
+
output_filename = filename_with_extension(a_file->filename[i], ".epub");
|
|
382
|
+
break;
|
|
383
|
+
|
|
384
|
+
case FORMAT_TEXTBUNDLE:
|
|
385
|
+
output_filename = filename_with_extension(a_file->filename[i], ".textbundle");
|
|
386
|
+
break;
|
|
387
|
+
|
|
388
|
+
case FORMAT_TEXTBUNDLE_COMPRESSED:
|
|
389
|
+
output_filename = filename_with_extension(a_file->filename[i], ".textpack");
|
|
390
|
+
break;
|
|
391
|
+
|
|
392
|
+
case FORMAT_OPML:
|
|
393
|
+
output_filename = filename_with_extension(a_file->filename[i], ".opml");
|
|
394
|
+
break;
|
|
395
|
+
|
|
396
|
+
case FORMAT_ITMZ:
|
|
397
|
+
output_filename = filename_with_extension(a_file->filename[i], ".itmz");
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Perform transclusion(s)
|
|
402
|
+
char * folder = dirname((char *) a_file->filename[i]);
|
|
403
|
+
|
|
404
|
+
if (!(extensions & EXT_COMPATIBILITY)) {
|
|
405
|
+
mmd_prepend_mmd_header(buffer);
|
|
406
|
+
mmd_append_mmd_footer(buffer);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (extensions & EXT_TRANSCLUDE) {
|
|
410
|
+
mmd_transclude_source(buffer, folder, a_file->filename[i], format, NULL, NULL);
|
|
411
|
+
|
|
412
|
+
// Don't free folder -- owned by dirname
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Perform block level CriticMarkup?
|
|
416
|
+
if (extensions & EXT_CRITIC_ACCEPT) {
|
|
417
|
+
mmd_critic_markup_accept(buffer);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (extensions & EXT_CRITIC_REJECT) {
|
|
421
|
+
mmd_critic_markup_reject(buffer);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Increment counter and prepare token pool
|
|
425
|
+
#ifdef kUseObjectPool
|
|
426
|
+
token_pool_init();
|
|
427
|
+
#endif
|
|
428
|
+
|
|
429
|
+
if (a_meta->count > 0) {
|
|
430
|
+
// List metadata keys
|
|
431
|
+
char_result = mmd_string_metadata_keys(buffer->str);
|
|
432
|
+
|
|
433
|
+
if (char_result) {
|
|
434
|
+
fputs(char_result, stdout);
|
|
435
|
+
|
|
436
|
+
free(char_result);
|
|
437
|
+
}
|
|
438
|
+
} else if (a_extract->count > 0) {
|
|
439
|
+
// Extract metadata key
|
|
440
|
+
const char * query = a_extract->sval[0];
|
|
441
|
+
|
|
442
|
+
char_result = mmd_string_metavalue_for_key(buffer->str, query);
|
|
443
|
+
|
|
444
|
+
if (char_result) {
|
|
445
|
+
fputs(char_result, stdout);
|
|
446
|
+
fputc('\n', stdout);
|
|
447
|
+
|
|
448
|
+
free(char_result);
|
|
449
|
+
}
|
|
450
|
+
} else {
|
|
451
|
+
// Regular processing
|
|
452
|
+
|
|
453
|
+
result = mmd_d_string_convert_to_data(buffer, extensions, format, language, folder);
|
|
454
|
+
|
|
455
|
+
if (FORMAT_TEXTBUNDLE == format) {
|
|
456
|
+
unzip_data_to_path(result->str, result->currentStringLength, output_filename);
|
|
457
|
+
} else {
|
|
458
|
+
if (!(output_stream = fopen(output_filename, "wb"))) {
|
|
459
|
+
// Failed to open file
|
|
460
|
+
perror(output_filename);
|
|
461
|
+
} else {
|
|
462
|
+
fwrite(result->str, result->currentStringLength, 1, output_stream);
|
|
463
|
+
fclose(output_stream);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
d_string_free(result, true);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
d_string_free(buffer, true);
|
|
471
|
+
free(output_filename);
|
|
472
|
+
|
|
473
|
+
// Decrement counter and drain
|
|
474
|
+
#ifdef kUseObjectPool
|
|
475
|
+
token_pool_drain();
|
|
476
|
+
#endif
|
|
477
|
+
}
|
|
478
|
+
} else {
|
|
479
|
+
if (a_file->count) {
|
|
480
|
+
// We have files to process
|
|
481
|
+
buffer = d_string_new("");
|
|
482
|
+
DString * file_buffer;
|
|
483
|
+
|
|
484
|
+
// Concatenate all input files
|
|
485
|
+
for (int i = 0; i < a_file->count; ++i) {
|
|
486
|
+
file_buffer = scan_file(a_file->filename[i]);
|
|
487
|
+
|
|
488
|
+
if (file_buffer == NULL) {
|
|
489
|
+
fprintf(stderr, "Error reading file '%s'\n", a_file->filename[i]);
|
|
490
|
+
exitcode = 1;
|
|
491
|
+
goto exit;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
d_string_append_c_array(buffer, file_buffer->str, file_buffer->currentStringLength);
|
|
495
|
+
d_string_free(file_buffer, true);
|
|
496
|
+
}
|
|
497
|
+
} else {
|
|
498
|
+
// Obtain input from stdin
|
|
499
|
+
buffer = stdin_buffer();
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
char * folder = NULL;
|
|
503
|
+
|
|
504
|
+
if (!(extensions & EXT_COMPATIBILITY)) {
|
|
505
|
+
mmd_prepend_mmd_header(buffer);
|
|
506
|
+
mmd_append_mmd_footer(buffer);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
if ((extensions & EXT_TRANSCLUDE) && (a_file->count == 1)) {
|
|
510
|
+
// Perform transclusion(s)
|
|
511
|
+
|
|
512
|
+
// Convert to absolute path for first file to enable proper path resolution
|
|
513
|
+
#ifdef PATH_MAX
|
|
514
|
+
// If PATH_MAX defined, use it
|
|
515
|
+
char absolute[PATH_MAX + 1];
|
|
516
|
+
realpath(a_file->filename[0], absolute);
|
|
517
|
+
folder = dirname((char *) a_file->filename[0]);
|
|
518
|
+
|
|
519
|
+
mmd_transclude_source(buffer, folder, absolute, format, NULL, NULL);
|
|
520
|
+
#else
|
|
521
|
+
// If undefined, then we *should* be able to use a NULL pointer to allocate
|
|
522
|
+
char * absolute = realpath(a_file->filename[0], NULL);
|
|
523
|
+
folder = dirname((char *) a_file->filename[0]);
|
|
524
|
+
mmd_transclude_source(buffer, folder, absolute, format, NULL, NULL);
|
|
525
|
+
free(absolute);
|
|
526
|
+
#endif
|
|
527
|
+
// Don't free folder -- owned by dirname
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
if (a_file->count == 1) {
|
|
531
|
+
// Must do this after realpath, b/c on some OS's (e.g. Travis-CI linux)
|
|
532
|
+
// this truncates a_file->filename[0]
|
|
533
|
+
folder = dirname((char *) a_file->filename[0]);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// Perform block level CriticMarkup?
|
|
537
|
+
if (extensions & EXT_CRITIC_ACCEPT) {
|
|
538
|
+
mmd_critic_markup_accept(buffer);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
if (extensions & EXT_CRITIC_REJECT) {
|
|
542
|
+
mmd_critic_markup_reject(buffer);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
if (a_meta->count > 0) {
|
|
546
|
+
// List metadata keys
|
|
547
|
+
char_result = mmd_string_metadata_keys(buffer->str);
|
|
548
|
+
|
|
549
|
+
if (char_result) {
|
|
550
|
+
fputs(char_result, stdout);
|
|
551
|
+
|
|
552
|
+
free(char_result);
|
|
553
|
+
}
|
|
554
|
+
} else if (a_extract->count > 0) {
|
|
555
|
+
// Extract metadata key
|
|
556
|
+
const char * query = a_extract->sval[0];
|
|
557
|
+
|
|
558
|
+
char_result = mmd_string_metavalue_for_key(buffer->str, query);
|
|
559
|
+
|
|
560
|
+
if (char_result) {
|
|
561
|
+
fputs(char_result, stdout);
|
|
562
|
+
fputc('\n', stdout);
|
|
563
|
+
|
|
564
|
+
free(char_result);
|
|
565
|
+
}
|
|
566
|
+
} else {
|
|
567
|
+
// Regular processing
|
|
568
|
+
|
|
569
|
+
result = mmd_d_string_convert_to_data(buffer, extensions, format, language, folder);
|
|
570
|
+
|
|
571
|
+
// Where does output go?
|
|
572
|
+
if (strcmp(a_o->filename[0], "-") == 0) {
|
|
573
|
+
// direct to stdout
|
|
574
|
+
output_stream = stdout;
|
|
575
|
+
} else if (!(output_stream = fopen(a_o->filename[0], "wb"))) {
|
|
576
|
+
perror(a_o->filename[0]);
|
|
577
|
+
free(result);
|
|
578
|
+
d_string_free(buffer, true);
|
|
579
|
+
|
|
580
|
+
exitcode = 1;
|
|
581
|
+
goto exit;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
fwrite(result->str, result->currentStringLength, 1, output_stream);
|
|
585
|
+
|
|
586
|
+
if (output_stream != stdout) {
|
|
587
|
+
fclose(output_stream);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
d_string_free(result, true);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
d_string_free(buffer, true);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
exit:
|
|
598
|
+
|
|
599
|
+
#ifdef kUseObjectPool
|
|
600
|
+
// Decrement counter and clean up token pool
|
|
601
|
+
token_pool_drain();
|
|
602
|
+
|
|
603
|
+
token_pool_free();
|
|
604
|
+
#endif
|
|
605
|
+
|
|
606
|
+
exit2:
|
|
607
|
+
|
|
608
|
+
// Clean up after argtable
|
|
609
|
+
arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
|
|
610
|
+
return exitcode;
|
|
611
|
+
}
|
|
612
|
+
|
data/ext/mmd/memoir.c
CHANGED
|
@@ -102,7 +102,10 @@ void mmd_export_token_memoir(DString * out, const char * source, token * t, scra
|
|
|
102
102
|
d_string_append_c_array(out, &source[t->child->next->start], temp_token->start - t->child->next->start);
|
|
103
103
|
scratch->padded = 1;
|
|
104
104
|
} else {
|
|
105
|
-
|
|
105
|
+
if (t->child->next) {
|
|
106
|
+
d_string_append_c_array(out, &source[t->child->start + t->child->len], t->start + t->len - t->child->next->start);
|
|
107
|
+
}
|
|
108
|
+
|
|
106
109
|
scratch->padded = 0;
|
|
107
110
|
}
|
|
108
111
|
}
|