diff options
author | Devin Torres <devin@devintorr.es> | 2014-03-25 12:58:13 -0500 |
---|---|---|
committer | Devin Torres <devin@devintorr.es> | 2014-03-25 12:58:13 -0500 |
commit | d7de54037618d47d523548bd2824fab5b1e742aa (patch) | |
tree | 5f603d0013609a2f833989b07a3d0087ff5c7d05 | |
parent | 6e7624195a0ce053852a39c2f1af62411032d696 (diff) | |
parent | b6f7a30cdbc4a26c1050af87082d388c2aa971cb (diff) | |
download | rust-hoedown-d7de54037618d47d523548bd2824fab5b1e742aa.tar.gz |
Merge pull request #65 from jmendeth/option-parsing-final
Improve executables (mainly option parsing)
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | Makefile.win | 8 | ||||
-rw-r--r-- | bin/common.h | 45 | ||||
-rw-r--r-- | bin/hoedown.c | 502 | ||||
-rw-r--r-- | bin/smartypants.c | 245 | ||||
-rw-r--r-- | examples/hoedown.c | 80 | ||||
-rw-r--r-- | examples/smartypants.c | 70 | ||||
-rw-r--r-- | src/document.h | 28 |
8 files changed, 813 insertions, 171 deletions
@@ -32,10 +32,10 @@ libhoedown.a: $(HOEDOWN_SRC) # Executables -hoedown: examples/hoedown.o $(HOEDOWN_SRC) +hoedown: bin/hoedown.o $(HOEDOWN_SRC) $(CC) $(LDFLAGS) $^ -o $@ -smartypants: examples/smartypants.o $(HOEDOWN_SRC) +smartypants: bin/smartypants.o $(HOEDOWN_SRC) $(CC) $(LDFLAGS) $^ -o $@ # Perfect hashing @@ -55,7 +55,7 @@ test-pl: hoedown # Housekeeping clean: - $(RM) src/*.o examples/*.o + $(RM) src/*.o bin/*.o $(RM) libhoedown.so libhoedown.so.1 libhoedown.a $(RM) hoedown smartypants hoedown.exe smartypants.exe diff --git a/Makefile.win b/Makefile.win index a28326b..cda24b9 100644 --- a/Makefile.win +++ b/Makefile.win @@ -17,11 +17,11 @@ all: hoedown.dll hoedown.exe smartypants.exe hoedown.dll: $(HOEDOWN_SRC) hoedown.def $(CC) $(HOEDOWN_SRC) hoedown.def /link /DLL $(LDFLAGS) /out:$@ -hoedown.exe: examples\hoedown.obj $(HOEDOWN_SRC) - $(CC) examples\hoedown.obj $(HOEDOWN_SRC) /link $(LDFLAGS) /out:$@ +hoedown.exe: bin\hoedown.obj $(HOEDOWN_SRC) + $(CC) bin\hoedown.obj $(HOEDOWN_SRC) /link $(LDFLAGS) /out:$@ -smartypants.exe: examples\smartypants.obj $(HOEDOWN_SRC) - $(CC) examples\smartypants.obj $(HOEDOWN_SRC) /link $(LDFLAGS) /out:$@ +smartypants.exe: bin\smartypants.obj $(HOEDOWN_SRC) + $(CC) bin\smartypants.obj $(HOEDOWN_SRC) /link $(LDFLAGS) /out:$@ # Housekeeping diff --git a/bin/common.h b/bin/common.h new file mode 100644 index 0000000..9074bd6 --- /dev/null +++ b/bin/common.h @@ -0,0 +1,45 @@ +#include "version.h" + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define str(x) __str(x) +#define __str(x) #x + +#define count_of(arr) (sizeof(arr)/sizeof(0[arr])) + +int +parseint(const char *string, long *result) { + char *end; + errno = 0; + *result = strtol(string, &end, 10); + return !(*end || errno); +} + +const char * +strprefix(const char *str, const char *prefix) { + while (*prefix) { + if (!(*str && *str == *prefix)) return 0; + prefix++; str++; + } + return str; +} + +void +print_option(char short_opt, const char *long_opt, const char *description) { + if (short_opt) + printf(" -%c, ", short_opt); + else + printf(" "); + + printf("--%-13s %s\n", long_opt, description); +} + +void +print_version() { + int major, minor, revision; + hoedown_version(&major, &minor, &revision); + printf("Built with Hoedown v%d.%d.%d.\n", major, minor, revision); +} diff --git a/bin/hoedown.c b/bin/hoedown.c new file mode 100644 index 0000000..960bb3e --- /dev/null +++ b/bin/hoedown.c @@ -0,0 +1,502 @@ +#include "document.h" +#include "html.h" + +#include "common.h" +//#include <time.h> + +/* NULL RENDERER */ + +enum renderer_type { + RENDERER_HTML, + RENDERER_HTML_TOC, + RENDERER_NULL, +}; + +hoedown_renderer * +null_renderer_new() { + hoedown_renderer *rend = malloc(sizeof(hoedown_renderer)); + if (rend) + memset(rend, 0x00, sizeof(hoedown_renderer)); + return rend; +} + +void +null_renderer_free(hoedown_renderer *rend) { + free(rend); +} + + +/* FEATURES INFO / DEFAULTS */ + +struct extension_category_info { + unsigned int flags; + const char *option_name; + const char *label; +}; + +struct extension_info { + unsigned int flag; + const char *option_name; + const char *description; +}; + +struct html_flag_info { + unsigned int flag; + const char *option_name; + const char *description; +}; + +static struct extension_category_info categories_info[] = { + {HOEDOWN_EXT_BLOCK, "block", "Block extensions"}, + {HOEDOWN_EXT_SPAN, "span", "Span extensions"}, + {HOEDOWN_EXT_FLAGS, "flags", "Other flags"}, + {HOEDOWN_EXT_NEGATIVE, "negative", "Negative flags"}, +}; + +static struct extension_info extensions_info[] = { + {HOEDOWN_EXT_TABLES, "tables", "Parse PHP-Markdown style tables."}, + {HOEDOWN_EXT_FENCED_CODE, "fenced-code", "Parse fenced code blocks."}, + {HOEDOWN_EXT_FOOTNOTES, "footnotes", "Parse footnotes."}, + + {HOEDOWN_EXT_AUTOLINK, "autolink", "Automatically turn URLs into links."}, + {HOEDOWN_EXT_STRIKETHROUGH, "strikethrough", "Parse ~~stikethrough~~ spans."}, + {HOEDOWN_EXT_UNDERLINE, "underline", "Parse _underline_ instead of emphasis."}, + {HOEDOWN_EXT_HIGHLIGHT, "highlight", "Parse ==highlight== spans."}, + {HOEDOWN_EXT_QUOTE, "quote", "Render \"quotes\" as <q>quotes</q>."}, + {HOEDOWN_EXT_SUPERSCRIPT, "superscript", "Parse super^script."}, + + {HOEDOWN_EXT_LAX_SPACING, "lax-spacing", "Allow HTML blocks on the same line as text."}, + {HOEDOWN_EXT_NO_INTRA_EMPHASIS, "disable-intra-emphasis", "Disable emphasis_between_words."}, + {HOEDOWN_EXT_SPACE_HEADERS, "space-headers", "Require a space after '#' in headers."}, + + {HOEDOWN_EXT_DISABLE_INDENTED_CODE, "disable-indented-code", "Don't parse indented code blocks."}, +}; + +static struct html_flag_info html_flags_info[] = { + {HOEDOWN_HTML_SKIP_HTML, "skip-html", "Strip all HTML tags."}, + {HOEDOWN_HTML_SKIP_STYLE, "skip-style", "Strip <style> tags."}, + {HOEDOWN_HTML_SKIP_IMAGES, "skip-images", "Don't render images."}, + {HOEDOWN_HTML_SKIP_LINKS, "skip-links", "Don't render links."}, + {HOEDOWN_HTML_EXPAND_TABS, "expand-tabs", "Expand tabs to spaces."}, + {HOEDOWN_HTML_SAFELINK, "safelink", "Only allow links to safe protocols."}, + {HOEDOWN_HTML_TOC, "toc", "Produce links to the Table of Contents."}, + {HOEDOWN_HTML_HARD_WRAP, "hard-wrap", "Render each linebreak as <br>."}, + {HOEDOWN_HTML_USE_XHTML, "xhtml", "Render XHTML."}, + {HOEDOWN_HTML_ESCAPE, "escape", "Escape all HTML."}, +}; + +static const char *category_prefix = "all-"; +static const char *negative_prefix = "no-"; + +#define DEF_IUNIT 1024 +#define DEF_OUNIT 64 +#define DEF_MAX_NESTING 16 + + +/* PRINT HELP */ + +void +print_help(const char *basename) { + /* usage */ + printf("Usage: %s [OPTION]... [FILE]\n\n", basename); + + /* description */ + printf("Process the Markdown in FILE (or standard input) and render it to standard output, using the Hoedown library. " + "Parsing and rendering can be customized through the options below. The default is to parse pure markdown and output HTML.\n\n"); + + /* main options */ + printf("Main options:\n"); + print_option('n', "max-nesting=N", "Maximum level of block nesting parsed. Default is " str(DEF_MAX_NESTING) "."); + print_option('t', "toc-level=N", "Maximum level for headers included in the TOC. Implies '--toc'."); + print_option( 0, "html", "Render (X)HTML. The default."); + print_option( 0, "html-toc", "Render the Table of Contents in (X)HTML."); + print_option( 0, "null", "Use a special \"null\" renderer that has no callbacks."); + print_option('T', "time", "Show time spent in rendering."); + print_option('i', "input-unit=N", "Reading block size. Default is " str(DEF_IUNIT) "."); + print_option('o', "output-unit=N", "Writing block size. Default is " str(DEF_OUNIT) "."); + print_option('h', "help", "Print this help text."); + print_option('v', "version", "Print Hoedown version."); + printf("\n"); + + /* extensions */ + size_t i; + size_t e; + for (i = 0; i < count_of(categories_info); i++) { + struct extension_category_info *category = categories_info+i; + printf("%s (--%s%s):\n", category->label, category_prefix, category->option_name); + for (e = 0; e < count_of(extensions_info); e++) { + struct extension_info *extension = extensions_info+e; + if (extension->flag & category->flags) { + print_option( 0, extension->option_name, extension->description); + } + } + printf("\n"); + } + + /* html-specific */ + printf("HTML-specific options:\n"); + for (i = 0; i < count_of(html_flags_info); i++) { + struct html_flag_info *html_flag = html_flags_info+i; + print_option( 0, html_flag->option_name, html_flag->description); + } + printf("\n"); + + /* ending */ + printf("Flags and extensions can be negated by prepending 'no' to them, as in '--no-tables', '--no-span' or '--no-escape'. " + "Options are processed in order, so in case of contradictory options the last specified stands.\n\n"); + + printf("When FILE is '-', read standard input. If no FILE was given, read standard input. Use '--' to signal end of option parsing. " + "Exit status is 0 if no errors occured, 1 with option parsing errors, 4 with memory allocation errors or 5 with I/O errors.\n\n"); +} + + +/* MAIN LOGIC */ + +int +main(int argc, char **argv) +{ + int show_time = 0; + //struct timespec start, end; + + /* buffers */ + hoedown_buffer *ib, *ob; + size_t iunit = DEF_IUNIT, ounit = DEF_OUNIT; + + /* files */ + FILE *in = NULL; + + /* renderer */ + int toc_level = 0; + int renderer_type = RENDERER_HTML; + + /* document */ + hoedown_document *document; + unsigned int extensions = 0; + size_t max_nesting = DEF_MAX_NESTING; + + /* HTML renderer-specific */ + unsigned int html_flags = 0; + + + /* option parsing */ + int just_args = 0; + int i, j; + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + if (!arg[0]) continue; + + if (just_args || arg[0] != '-') { + /* regular argument */ + in = fopen(arg, "r"); + if (!in) { + fprintf(stderr, "Unable to open input file \"%s\": %s\n", arg, strerror(errno)); + return 5; + } + continue; + } + + if (!arg[1]) { + /* arg is "-" */ + in = stdin; + continue; + } + + if (arg[1] != '-') { + /* parse short options */ + char opt; + const char *val; + for (j = 1; (opt = arg[j]); j++) { + if (opt == 'h') { + print_help(argv[0]); + return 1; + } + + if (opt == 'v') { + print_version(); + return 1; + } + + if (opt == 'T') { + show_time = 1; + continue; + } + + /* options requiring value */ + if (arg[++j]) val = arg+j; + else if (argv[++i]) val = argv[i]; + else { + fprintf(stderr, "Wrong option '-%c' found.\n", opt); + return 1; + } + + long int num; + int isNum = parseint(val, &num); + + if (opt == 'n' && isNum) { + max_nesting = num; + break; + } + + if (opt == 't' && isNum) { + toc_level = num; + break; + } + + if (opt == 'i' && isNum) { + iunit = num; + break; + } + + if (opt == 'o' && isNum) { + ounit = num; + break; + } + + fprintf(stderr, "Wrong option '-%c' found.\n", opt); + return 1; + } + continue; + } + + if (!arg[2]) { + /* arg is "--" */ + just_args = 1; + continue; + } + + /* parse long option */ + char opt [100]; + strncpy(opt, arg+2, 100); + opt[99] = 0; + + char *val = strchr(opt, '='); + + long int num = 0; + int isNum = 0; + + if (val) { + *val = 0; + val++; + + if (*val) + isNum = parseint(val, &num); + } + + int opt_parsed = 0; + + if (strcmp(opt, "help")==0) { + print_help(argv[0]); + return 1; + } + + if (strcmp(opt, "version")==0) { + print_version(); + return 1; + } + + if (strcmp(opt, "max-nesting")==0 && isNum) { + opt_parsed = 1; + max_nesting = num; + } + if (strcmp(opt, "toc-level")==0 && isNum) { + opt_parsed = 1; + toc_level = num; + } + if (strcmp(opt, "input-unit")==0 && isNum) { + opt_parsed = 1; + iunit = num; + } + if (strcmp(opt, "output-unit")==0 && isNum) { + opt_parsed = 1; + ounit = num; + } + + if (strcmp(opt, "html")==0) { + opt_parsed = 1; + renderer_type = RENDERER_HTML; + } + if (strcmp(opt, "html-toc")==0) { + opt_parsed = 1; + renderer_type = RENDERER_HTML_TOC; + } + if (strcmp(opt, "null")==0) { + opt_parsed = 1; + renderer_type = RENDERER_NULL; + } + + const char *name; + size_t i; + + /* extension categories */ + if ((name = strprefix(opt, category_prefix))) { + for (i = 0; i < count_of(categories_info); i++) { + struct extension_category_info *category = categories_info+i; + if (strcmp(name, category->option_name)==0) { + opt_parsed = 1; + extensions |= category->flags; + break; + } + } + } + + /* extensions */ + for (i = 0; i < count_of(extensions_info); i++) { + struct extension_info *extension = extensions_info+i; + if (strcmp(opt, extension->option_name)==0) { + opt_parsed = 1; + extensions |= extension->flag; + break; + } + } + + /* html flags */ + for (i = 0; i < count_of(html_flags_info); i++) { + struct html_flag_info *html_flag = html_flags_info+i; + if (strcmp(opt, html_flag->option_name)==0) { + opt_parsed = 1; + html_flags |= html_flag->flag; + break; + } + } + + /* negations */ + if ((name = strprefix(opt, negative_prefix))) { + for (i = 0; i < count_of(categories_info); i++) { + struct extension_category_info *category = categories_info+i; + if (strcmp(name, category->option_name)==0) { + opt_parsed = 1; + extensions &= ~(category->flags); + break; + } + } + for (i = 0; i < count_of(extensions_info); i++) { + struct extension_info *extension = extensions_info+i; + if (strcmp(name, extension->option_name)==0) { + opt_parsed = 1; + extensions &= ~(extension->flag); + break; + } + } + for (i = 0; i < count_of(html_flags_info); i++) { + struct html_flag_info *html_flag = html_flags_info+i; + if (strcmp(name, html_flag->option_name)==0) { + opt_parsed = 1; + html_flags &= ~(html_flag->flag); + break; + } + } + } + + if (strcmp(opt, "time")==0) { + opt_parsed = 1; + show_time = 1; + } + + if (!opt_parsed) { + fprintf(stderr, "Wrong option '%s' found.\n", arg); + return 1; + } + } + + if (!in) + in = stdin; + + + /* reading everything */ + ib = hoedown_buffer_new(iunit); + if (!ib) { + fprintf(stderr, "Couldn't allocate input buffer.\n"); + return 4; + } + + while (!feof(in)) { + if (ferror(in)) { + fprintf(stderr, "I/O errors found while reading input.\n"); + return 5; + } + if (hoedown_buffer_grow(ib, ib->size + iunit) != HOEDOWN_BUF_OK) { + fprintf(stderr, "Couldn't grow input buffer.\n"); + return 4; + } + ib->size += fread(ib->data + ib->size, 1, iunit, in); + } + + if (in != stdin) + fclose(in); + + + /* creating the renderer */ + hoedown_renderer *renderer; + void (*renderer_free)(hoedown_renderer*); + + switch (renderer_type) { + case RENDERER_HTML: + renderer = hoedown_html_renderer_new(html_flags, toc_level); + renderer_free = hoedown_html_renderer_free; + break; + case RENDERER_HTML_TOC: + renderer = hoedown_html_toc_renderer_new(toc_level); + renderer_free = hoedown_html_renderer_free; + break; + case RENDERER_NULL: + renderer = null_renderer_new(); + renderer_free = null_renderer_free; + break; + default: + renderer = NULL; + }; + + if (!renderer) { + fprintf(stderr, "Couldn't allocate renderer.\n"); + return 4; + } + + + /* performing markdown rendering */ + ob = hoedown_buffer_new(ounit); + if (!ob) { + fprintf(stderr, "Couldn't allocate output buffer.\n"); + return 4; + } + + document = hoedown_document_new(renderer, extensions, max_nesting); + if (!document) { + fprintf(stderr, "Couldn't allocate document parser.\n"); + return 4; + } + + //clock_gettime(CLOCK_MONOTONIC, &start); + hoedown_document_render(document, ob, ib->data, ib->size); + //clock_gettime(CLOCK_MONOTONIC, &end); + + + /* writing the result to stdout */ + (void)fwrite(ob->data, 1, ob->size, stdout); + + + /* showing rendering time */ + if (show_time) { + //TODO: enable this + //long long elapsed = ( end.tv_sec*1000000000 + end.tv_nsec) + // - (start.tv_sec*1000000000 + start.tv_nsec); + //if (elapsed < 1000000000) + // fprintf(stderr, "Time spent on rendering: %.2f ms.\n", ((double)elapsed)/1000000); + //else + // fprintf(stderr, "Time spent on rendering: %.3f s.\n", ((double)elapsed)/1000000000); + } + + + /* cleanup */ + hoedown_buffer_free(ib); + hoedown_buffer_free(ob); + + hoedown_document_free(document); + renderer_free(renderer); + + if (ferror(stdout)) { + fprintf(stderr, "I/O errors found while writing output.\n"); + return 5; + } + + return 0; +} diff --git a/bin/smartypants.c b/bin/smartypants.c new file mode 100644 index 0000000..5550157 --- /dev/null +++ b/bin/smartypants.c @@ -0,0 +1,245 @@ +#include "html.h" + +#include "common.h" +//#include <time.h> + +#define DEF_IUNIT 1024 +#define DEF_OUNIT 64 +#define DEF_MAX_NESTING 16 + + +/* PRINT HELP */ + +void +print_help(const char *basename) { + /* usage */ + printf("Usage: %s [OPTION]... [FILE]\n\n", basename); + + /* description */ + printf("Apply SmartyPants smart punctuation to the HTML in FILE (or standard input), and output the resulting HTML to standard output.\n\n"); + + /* main options */ + printf("Main options:\n"); + print_option('T', "time", "Show time spent in SmartyPants processing."); + print_option('i', "input-unit=N", "Reading block size. Default is " str(DEF_IUNIT) "."); + print_option('o', "output-unit=N", "Writing block size. Default is " str(DEF_OUNIT) "."); + print_option('h', "help", "Print this help text."); + print_option('v', "version", "Print Hoedown version."); + printf("\n"); + + /* ending */ + printf("Options are processed in order, so in case of contradictory options the last specified stands.\n\n"); + + printf("When FILE is '-', read standard input. If no FILE was given, read standard input. Use '--' to signal end of option parsing. " + "Exit status is 0 if no errors occured, 1 with option parsing errors, 4 with memory allocation errors or 5 with I/O errors.\n\n"); +} + + +/* MAIN LOGIC */ + +int +main(int argc, char **argv) +{ + int show_time = 0; + //struct timespec start, end; + + /* buffers */ + hoedown_buffer *ib, *ob; + size_t iunit = DEF_IUNIT, ounit = DEF_OUNIT; + + /* files */ + FILE *in = NULL; + + + /* option parsing */ + int just_args = 0; + int i, j; + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + if (!arg[0]) continue; + + if (just_args || arg[0] != '-') { + /* regular argument */ + in = fopen(arg, "r"); + if (!in) { + fprintf(stderr, "Unable to open input file \"%s\": %s\n", arg, strerror(errno)); + return 5; + } + continue; + } + + if (!arg[1]) { + /* arg is "-" */ + in = stdin; + continue; + } + + if (arg[1] != '-') { + /* parse short options */ + char opt; + const char *val; + for (j = 1; (opt = arg[j]); j++) { + if (opt == 'h') { + print_help(argv[0]); + return 1; + } + + if (opt == 'v') { + print_version(); + return 1; + } + + if (opt == 'T') { + show_time = 1; + continue; + } + + /* options requiring value */ + if (arg[++j]) val = arg+j; + else if (argv[++i]) val = argv[i]; + else { + fprintf(stderr, "Wrong option '-%c' found.\n", opt); + return 1; + } + + long int num; + int isNum = parseint(val, &num); + + if (opt == 'i' && isNum) { + iunit = num; + break; + } + + if (opt == 'o' && isNum) { + ounit = num; + break; + } + + fprintf(stderr, "Wrong option '-%c' found.\n", opt); + return 1; + } + continue; + } + + if (!arg[2]) { + /* arg is "--" */ + just_args = 1; + continue; + } + + /* parse long option */ + char opt [100]; + strncpy(opt, arg+2, 100); + opt[99] = 0; + + char *val = strchr(opt, '='); + + long int num = 0; + int isNum = 0; + + if (val) { + *val = 0; + val++; + + if (*val) + isNum = parseint(val, &num); + } + + int opt_parsed = 0; + + if (strcmp(opt, "help")==0) { + print_help(argv[0]); + return 1; + } + + if (strcmp(opt, "version")==0) { + print_version(); + return 1; + } + + if (strcmp(opt, "input-unit")==0 && isNum) { + opt_parsed = 1; + iunit = num; + } + if (strcmp(opt, "output-unit")==0 && isNum) { + opt_parsed = 1; + ounit = num; + } + + if (strcmp(opt, "time")==0) { + opt_parsed = 1; + show_time = 1; + } + + if (!opt_parsed) { + fprintf(stderr, "Wrong option '%s' found.\n", arg); + return 1; + } + } + + if (!in) + in = stdin; + + + /* reading everything */ + ib = hoedown_buffer_new(iunit); + if (!ib) { + fprintf(stderr, "Couldn't allocate input buffer.\n"); + return 4; + } + + while (!feof(in)) { + if (ferror(in)) { + fprintf(stderr, "I/O errors found while reading input.\n"); + return 5; + } + if (hoedown_buffer_grow(ib, ib->size + iunit) != HOEDOWN_BUF_OK) { + fprintf(stderr, "Couldn't grow input buffer.\n"); + return 4; + } + ib->size += fread(ib->data + ib->size, 1, iunit, in); + } + + if (in != stdin) + fclose(in); + + + /* performing SmartyPants processing */ + ob = hoedown_buffer_new(ounit); + if (!ob) { + fprintf(stderr, "Couldn't allocate output buffer.\n"); + return 4; + } + + //clock_gettime(CLOCK_MONOTONIC, &start); + hoedown_html_smartypants(ob, ib->data, ib->size); + //clock_gettime(CLOCK_MONOTONIC, &end); + + + /* writing the result to stdout */ + (void)fwrite(ob->data, 1, ob->size, stdout); + + + /* showing rendering time */ + if (show_time) { + //TODO: enable this + //long long elapsed = ( end.tv_sec*1000000000 + end.tv_nsec) + // - (start.tv_sec*1000000000 + start.tv_nsec); + //if (elapsed < 1000000000) + // fprintf(stderr, "Time spent on rendering: %.2f ms.\n", ((double)elapsed)/1000000); + //else + // fprintf(stderr, "Time spent on rendering: %.3f s.\n", ((double)elapsed)/1000000000); + } + + + /* cleanup */ + hoedown_buffer_free(ib); + hoedown_buffer_free(ob); + + if (ferror(stdout)) { + fprintf(stderr, "I/O errors found while writing output.\n"); + return 5; + } + + return 0; +} diff --git a/examples/hoedown.c b/examples/hoedown.c deleted file mode 100644 index 293ab5f..0000000 --- a/examples/hoedown.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "document.h" -#include "html.h" - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define READ_UNIT 1024 -#define OUTPUT_UNIT 64 - -int -main(int argc, char **argv) -{ - hoedown_buffer *ib, *ob; - FILE *in = stdin; - - hoedown_renderer *renderer; - hoedown_document *document; - - /* opening the file if given from the command line */ - if (argc > 1) { - in = fopen(argv[1], "r"); - if (!in) { - fprintf(stderr, "Unable to open input file \"%s\": %s\n", argv[1], strerror(errno)); - return 1; - } - } - - /* reading everything */ - ib = hoedown_buffer_new(READ_UNIT); - if (!ib) { - fprintf(stderr, "Couldn't allocate input buffer.\n"); - return 1; - } - - while (!feof(in)) { - if (ferror(in)) { - fprintf(stderr, "I/O errors found while reading input.\n"); - return 1; - } - if (hoedown_buffer_grow(ib, ib->size + READ_UNIT) != HOEDOWN_BUF_OK) { - fprintf(stderr, "Couldn't grow input buffer.\n"); - return 1; - } - ib->size += fread(ib->data + ib->size, 1, READ_UNIT, in); - } - - if (in != stdin) - fclose(in); - - /* performing markdown parsing */ - ob = hoedown_buffer_new(OUTPUT_UNIT); - if (!ob) { - fprintf(stderr, "Couldn't allocate output buffer.\n"); - return 1; - } - - renderer = hoedown_html_renderer_new(0, 0); - document = hoedown_document_new(renderer, 0, 16); - - hoedown_document_render(document, ob, ib->data, ib->size); - - hoedown_document_free(document); - hoedown_html_renderer_free(renderer); - - /* writing the result to stdout */ - (void)fwrite(ob->data, 1, ob->size, stdout); - - /* cleanup */ - hoedown_buffer_free(ib); - hoedown_buffer_free(ob); - - if (ferror(stdout)) { - fprintf(stderr, "I/O errors found while writing output.\n"); - return 1; - } - - return 0; -} diff --git a/examples/smartypants.c b/examples/smartypants.c deleted file mode 100644 index 4a367ef..0000000 --- a/examples/smartypants.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "html.h" - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define READ_UNIT 1024 -#define OUTPUT_UNIT 64 - -int -main(int argc, char **argv) -{ - hoedown_buffer *ib, *ob; - FILE *in = stdin; - - /* opening the file if given from the command line */ - if (argc > 1) { - in = fopen(argv[1], "r"); - if (!in) { - fprintf(stderr, "Unable to open input file \"%s\": %s\n", argv[1], strerror(errno)); - return 1; - } - } - - /* reading everything */ - ib = hoedown_buffer_new(READ_UNIT); - if (!ib) { - fprintf(stderr, "Couldn't allocate input buffer.\n"); - return 1; - } - - while (!feof(in)) { - if (ferror(in)) { - fprintf(stderr, "I/O error found while reading input.\n"); - return 1; - } - if (hoedown_buffer_grow(ib, ib->size + READ_UNIT) != HOEDOWN_BUF_OK) { - fprintf(stderr, "Couldn't grow input buffer.\n"); - return 1; - } - ib->size += fread(ib->data + ib->size, 1, READ_UNIT, in); - } - - if (in != stdin) - fclose(in); - - /* performing SmartyPants parsing */ - ob = hoedown_buffer_new(OUTPUT_UNIT); - if (!ob) { - fprintf(stderr, "Couldn't allocate output buffer.\n"); - return 1; - } - - hoedown_html_smartypants(ob, ib->data, ib->size); - - /* writing the result to stdout */ - (void)fwrite(ob->data, 1, ob->size, stdout); - - /* cleanup */ - hoedown_buffer_free(ib); - hoedown_buffer_free(ob); - - if (ferror(stdout)) { - fprintf(stderr, "I/O errors found while writing output.\n"); - return 1; - } - - return 0; -} diff --git a/src/document.h b/src/document.h index e3007bd..d310933 100644 --- a/src/document.h +++ b/src/document.h @@ -16,29 +16,28 @@ extern "C" { enum hoedown_extensions { /* block-level extensions */ - HOEDOWN_EXT_SPACE_HEADERS = (1 << 0), - HOEDOWN_EXT_TABLES = (1 << 1), - HOEDOWN_EXT_FENCED_CODE = (1 << 2), - HOEDOWN_EXT_FOOTNOTES = (1 << 3), + HOEDOWN_EXT_TABLES = (1 << 0), + HOEDOWN_EXT_FENCED_CODE = (1 << 1), + HOEDOWN_EXT_FOOTNOTES = (1 << 2), /* span-level extensions */ - HOEDOWN_EXT_AUTOLINK = (1 << 4), - HOEDOWN_EXT_STRIKETHROUGH = (1 << 5), - HOEDOWN_EXT_UNDERLINE = (1 << 6), - HOEDOWN_EXT_HIGHLIGHT = (1 << 7), - HOEDOWN_EXT_QUOTE = (1 << 8), - HOEDOWN_EXT_SUPERSCRIPT = (1 << 9), + HOEDOWN_EXT_AUTOLINK = (1 << 3), + HOEDOWN_EXT_STRIKETHROUGH = (1 << 4), + HOEDOWN_EXT_UNDERLINE = (1 << 5), + HOEDOWN_EXT_HIGHLIGHT = (1 << 6), + HOEDOWN_EXT_QUOTE = (1 << 7), + HOEDOWN_EXT_SUPERSCRIPT = (1 << 8), /* other flags */ - HOEDOWN_EXT_LAX_SPACING = (1 << 10), - HOEDOWN_EXT_NO_INTRA_EMPHASIS = (1 << 11), + HOEDOWN_EXT_LAX_SPACING = (1 << 9), + HOEDOWN_EXT_NO_INTRA_EMPHASIS = (1 << 10), + HOEDOWN_EXT_SPACE_HEADERS = (1 << 11), /* negative flags */ HOEDOWN_EXT_DISABLE_INDENTED_CODE = (1 << 12) }; #define HOEDOWN_EXT_BLOCK (\ - HOEDOWN_EXT_SPACE_HEADERS |\ HOEDOWN_EXT_TABLES |\ HOEDOWN_EXT_FENCED_CODE |\ HOEDOWN_EXT_FOOTNOTES ) @@ -53,7 +52,8 @@ enum hoedown_extensions { #define HOEDOWN_EXT_FLAGS (\ HOEDOWN_EXT_LAX_SPACING |\ - HOEDOWN_EXT_NO_INTRA_EMPHASIS ) + HOEDOWN_EXT_NO_INTRA_EMPHASIS |\ + HOEDOWN_EXT_SPACE_HEADERS ) #define HOEDOWN_EXT_NEGATIVE (\ HOEDOWN_EXT_DISABLE_INDENTED_CODE ) |