#include #include #include "bstrlib.h" #include "stmd.h" #include "debug.h" static bstring format_str(bstring s) { int pos = 0; int len = blength(s); bstring result = bfromcstr(""); char c; bformata(result, "\""); while (pos < len) { c = bchar(s, pos); switch (c) { case '\n': bformata(result, "\\n"); break; case '"': bformata(result, "\\\""); break; case '\\': bformata(result, "\\\\"); break; default: bformata(result, "%c", c); } pos++; } bformata(result, "\""); return result; } // Functions to pretty-print inline and block lists, for debugging. // Prettyprint an inline list, for debugging. extern void print_blocks(block* b, int indent) { struct ListData * data; while(b != NULL) { // printf("%3d %3d %3d| ", b->start_line, b->start_column, b->end_line); for (int i=0; i < indent; i++) { putchar(' '); } switch(b->tag) { case document: printf("document\n"); print_blocks(b->children, indent + 2); break; case block_quote: printf("block_quote\n"); print_blocks(b->children, indent + 2); break; case list_item: data = &(b->attributes.list_data); printf("list_item\n"); print_blocks(b->children, indent + 2); break; case list: data = &(b->attributes.list_data); if (data->list_type == ordered) { printf("list (type=ordered tight=%s start=%d delim=%s)\n", (data->tight ? "true" : "false"), data->start, (data->delimiter == parens ? "parens" : "period")); } else { printf("list (type=bullet tight=%s bullet_char=%c)\n", (data->tight ? "true" : "false"), data->bullet_char); } print_blocks(b->children, indent + 2); break; case atx_header: printf("atx_header (level=%d)\n", b->attributes.header_level); print_inlines(b->inline_content, indent + 2); break; case setext_header: printf("setext_header (level=%d)\n", b->attributes.header_level); print_inlines(b->inline_content, indent + 2); break; case paragraph: printf("paragraph\n"); print_inlines(b->inline_content, indent + 2); break; case hrule: printf("hrule\n"); break; case indented_code: printf("indented_code %s\n", format_str(b->string_content)->data); break; case fenced_code: printf("fenced_code length=%d info=%s %s\n", b->attributes.fenced_code_data.fence_length, format_str(b->attributes.fenced_code_data.info)->data, format_str(b->string_content)->data); break; case html_block: printf("html_block %s\n", format_str(b->string_content)->data); break; case reference_def: printf("reference_def\n"); break; default: log_warn("block type %d not implemented\n", b->tag); break; } b = b->next; } } // Prettyprint an inline list, for debugging. extern void print_inlines(inl* ils, int indent) { while(ils != NULL) { /* // we add 11 extra spaces for the line/column info for (int i=0; i < 11; i++) { putchar(' '); } putchar('|'); putchar(' '); */ for (int i=0; i < indent; i++) { putchar(' '); } switch(ils->tag) { case str: printf("str %s\n", format_str(ils->content.literal)->data); break; case linebreak: printf("linebreak\n"); break; case softbreak: printf("softbreak\n"); break; case code: printf("code %s\n", format_str(ils->content.literal)->data); break; case raw_html: printf("html %s\n", format_str(ils->content.literal)->data); break; case entity: printf("entity %s\n", format_str(ils->content.literal)->data); break; case link: printf("link url=%s title=%s\n", format_str(ils->content.linkable.url)->data, format_str(ils->content.linkable.title)->data); print_inlines(ils->content.linkable.label, indent + 2); break; case image: printf("image url=%s title=%s\n", format_str(ils->content.linkable.url)->data, format_str(ils->content.linkable.title)->data); print_inlines(ils->content.linkable.label, indent + 2); break; case strong: printf("strong\n"); print_inlines(ils->content.linkable.label, indent + 2); break; case emph: printf("emph\n"); print_inlines(ils->content.linkable.label, indent + 2); break; } ils = ils->next; } }