QString HoedownMarkdownConverter::renderAsTableOfContents(MarkdownDocument *document) { QString toc; if (document) { HoedownMarkdownDocument *doc = dynamic_cast<HoedownMarkdownDocument*>(document); if (doc->document()) { hoedown_buffer *in = doc->document(); hoedown_buffer *out = hoedown_buffer_new(64); hoedown_renderer *renderer = hoedown_html_toc_renderer_new(16); hoedown_markdown *markdown = hoedown_markdown_new(doc->options(), 16, renderer); hoedown_markdown_render(out, in->data, in->size, markdown); hoedown_markdown_free(markdown); hoedown_html_renderer_free(renderer); toc = QString::fromUtf8(hoedown_buffer_cstr(out)); hoedown_buffer_free(out); } } return toc; }
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); while (!feof(in)) { if (ferror(in)) { fprintf(stderr, "I/O errors found while reading input.\n"); return 5; } hoedown_buffer_grow(ib, ib->size + iunit); ib->size += fread(ib->data + ib->size, 1, iunit, in); } if (in != stdin) fclose(in); /* creating the renderer */ hoedown_renderer *renderer = NULL; void (*renderer_free)(hoedown_renderer*) = NULL; 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; }; /* performing markdown rendering */ ob = hoedown_buffer_new(ounit); document = hoedown_document_new(renderer, extensions, max_nesting); //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; }
int main(int argc, char **argv) { struct option_data data; clock_t t1, t2; FILE *file = stdin; hoedown_buffer *ib, *ob, *meta; hoedown_renderer *renderer = NULL; void (*renderer_free)(hoedown_renderer *) = NULL; hoedown_document *document; /* Parse options */ data.basename = argv[0]; data.done = 0; data.show_time = 0; data.iunit = DEF_IUNIT; data.ounit = DEF_OUNIT; data.filename = NULL; data.renderer = RENDERER_HTML; data.toc_level = 0; data.html_flags = 0; data.extensions = 0; data.max_nesting = DEF_MAX_NESTING; data.link_attributes = 0; argc = parse_options(argc, argv, parse_short_option, parse_long_option, parse_argument, &data); if (data.done) return 0; if (!argc) return 1; /* Add extesion flags, case html_flags */ if (data.html_flags & HOEDOWN_HTML_FENCED_CODE_SCRIPT) { data.extensions |= HOEDOWN_EXT_FENCED_CODE; } /* Open input file, if needed */ if (data.filename) { file = fopen(data.filename, "r"); if (!file) { fprintf(stderr, "Unable to open input file \"%s\": %s\n", data.filename, strerror(errno)); return 5; } } /* Read everything */ ib = hoedown_buffer_new(data.iunit); if (hoedown_buffer_putf(ib, file)) { fprintf(stderr, "I/O errors found while reading input.\n"); return 5; } if (file != stdin) fclose(file); /* Create the renderer */ switch (data.renderer) { case RENDERER_HTML: renderer = hoedown_html_renderer_new(data.html_flags, data.toc_level); renderer_free = hoedown_html_renderer_free; break; case RENDERER_HTML_TOC: renderer = hoedown_html_toc_renderer_new(data.toc_level); renderer_free = hoedown_html_renderer_free; break; case RENDERER_CONTEXT_TEST: renderer = hoedown_context_test_renderer_new(); renderer_free = hoedown_context_test_renderer_free; break; }; /* Perform Markdown rendering */ ob = hoedown_buffer_new(data.ounit); meta = hoedown_buffer_new(data.ounit); document = hoedown_document_new(renderer, data.extensions, data.max_nesting, NULL, meta); /* state */ if (data.renderer == RENDERER_CONTEXT_TEST) { hoedown_context_test_renderer_state *state; state = (hoedown_context_test_renderer_state *)renderer->opaque; state->doc = document; } else { hoedown_html_renderer_state *state; state = (hoedown_html_renderer_state *)renderer->opaque; /* toc_data */ if (data.toc_level > 0) { state->toc_data.current_level = 0; state->toc_data.level_offset = 0; state->toc_data.nesting_level = data.toc_level; state->toc_data.header = "<div class=\"toc\">"; state->toc_data.footer = "</div>"; } /* link_attributes */ if (data.link_attributes) { state->link_attributes = rndr_test_link_attributes; } } t1 = clock(); hoedown_document_render(document, ob, ib->data, ib->size); t2 = clock(); /* Cleanup */ hoedown_buffer_free(ib); hoedown_document_free(document); renderer_free(renderer); /* Write the result to stdout */ (void)fwrite(ob->data, 1, ob->size, stdout); hoedown_buffer_free(ob); if (ferror(stdout)) { hoedown_buffer_free(meta); fprintf(stderr, "I/O errors found while writing output.\n"); return 5; } /* Meta block */ if (meta->size > 0) { fprintf(stdout, "-- Meta Block --\n"); (void)fwrite(meta->data, 1, meta->size, stdout); } hoedown_buffer_free(meta); if (ferror(stdout)) { fprintf(stderr, "I/O errors found while writing output.\n"); return 5; } /* Show rendering time */ if (data.show_time) { double elapsed; if (t1 == ((clock_t) -1) || t2 == ((clock_t) -1)) { fprintf(stderr, "Failed to get the time.\n"); return 1; } elapsed = (double)(t2 - t1) / CLOCKS_PER_SEC; if (elapsed < 1) fprintf(stderr, "Time spent on rendering: %7.2f ms.\n", elapsed*1e3); else fprintf(stderr, "Time spent on rendering: %6.3f s.\n", elapsed); } return 0; }