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;
}
Exemple #2
0
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;
}
Exemple #3
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;
}