diff --git a/md2teach/main.c b/md2teach/main.c index 30d7691..c1f6d09 100644 --- a/md2teach/main.c +++ b/md2teach/main.c @@ -50,7 +50,7 @@ static void debugLogHook(const char * message, void * userdata); MD_PARSER parser = { 0, // abi_version - 0, // flags + MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS, // flags enterBlockHook, leaveBlockHook, enterSpanHook, @@ -60,42 +60,231 @@ MD_PARSER parser = { NULL // syntax }; +void * lowestStackSeen; +char * commandName; +int indentLevel = 0; + // Implementation static int enterBlockHook(MD_BLOCKTYPE type, void * detail, void * userdata) { - printf("Enter Block: type = %d, detail = %p\n", (int)type, detail); + if ((detail != NULL) && + (detail < lowestStackSeen)) + lowestStackSeen = detail; + + switch (type) { + case MD_BLOCK_DOC: + printf("%*sDOC {\n", indentLevel, ""); + break; + + case MD_BLOCK_QUOTE: + printf("%*sQUOTE {\n", indentLevel, ""); + break; + + case MD_BLOCK_UL: { + MD_BLOCK_UL_DETAIL * ulDetail = (MD_BLOCK_UL_DETAIL *)detail; + printf("%*sUL (is_tight=%d, mark=%c) {\n", indentLevel, "", ulDetail->is_tight, ulDetail->mark); + break; + } + + case MD_BLOCK_OL: { + MD_BLOCK_OL_DETAIL * olDetail = (MD_BLOCK_OL_DETAIL *)detail; + printf("%*sOL (start=%u, is_tight=%d, mark_delimiter=%c) {\n", indentLevel, "", olDetail->start, olDetail->is_tight, olDetail->mark_delimiter); + break; + } + + case MD_BLOCK_LI: + printf("%*sLI {\n", indentLevel, ""); + break; + + case MD_BLOCK_HR: + printf("%*sHR {\n", indentLevel, ""); + break; + + case MD_BLOCK_H: { + MD_BLOCK_H_DETAIL * hDetail = (MD_BLOCK_H_DETAIL *)detail; + printf("%*sH (level=%u) {\n", indentLevel, "", hDetail->level); + break; + } + + case MD_BLOCK_CODE: { + MD_BLOCK_CODE_DETAIL * codeDetail = (MD_BLOCK_CODE_DETAIL *)detail; + printf("%*sCODE ", indentLevel, ""); + if (codeDetail->fence_char != '\0') { + printf("(fence_char=%c) ", codeDetail->fence_char); + } + printf("{\n"); + break; + } + + case MD_BLOCK_P: + printf("%*sP {\n", indentLevel, ""); + break; + + default: + fprintf(stderr, "%s: Invalid block type (%d)\n", commandName, (int)type); + return 1; + break; + } + + indentLevel+=2; return 0; } static int leaveBlockHook(MD_BLOCKTYPE type, void * detail, void * userdata) { - printf("Leave Block: type = %d, detail = %p\n", (int)type, detail); + if ((detail != NULL) && + (detail < lowestStackSeen)) + lowestStackSeen = detail; + + switch (type) { + case MD_BLOCK_DOC: + break; + + case MD_BLOCK_QUOTE: + break; + + case MD_BLOCK_UL: + break; + + case MD_BLOCK_OL: + break; + + case MD_BLOCK_LI: + break; + + case MD_BLOCK_HR: + break; + + case MD_BLOCK_H: + break; + + case MD_BLOCK_CODE: + break; + + case MD_BLOCK_P: + break; + + default: + fprintf(stderr, "%s: Invalid block type (%d)\n", commandName, (int)type); + return 1; + break; + } + + indentLevel-=2; + printf("%*s}\n", indentLevel, ""); + return 0; } static int enterSpanHook(MD_SPANTYPE type, void * detail, void * userdata) { - printf("Enter Span: type = %d, detail = %p\n", (int)type, detail); + if ((detail != NULL) && + (detail < lowestStackSeen)) + lowestStackSeen = detail; + + switch (type) { + case MD_SPAN_EM: + printf("%*sEM {\n", indentLevel, ""); + break; + + case MD_SPAN_STRONG: + printf("%*sSTRONG {\n", indentLevel, ""); + break; + + case MD_SPAN_A: + printf("%*sA {\n", indentLevel, ""); + break; + + case MD_SPAN_IMG: + printf("%*sIMG {\n", indentLevel, ""); + break; + + case MD_SPAN_CODE: + printf("%*sCODE {\n", indentLevel, ""); + break; + + default: + fprintf(stderr, "%s: Invalid span type (%d)\n", commandName, (int)type); + return 1; + break; + } + + indentLevel+=2; return 0; } static int leaveSpanHook(MD_SPANTYPE type, void * detail, void * userdata) { - printf("Leave Span: type = %d, detail = %p\n", (int)type, detail); + if ((detail != NULL) && + (detail < lowestStackSeen)) + lowestStackSeen = detail; + + switch (type) { + case MD_SPAN_EM: + break; + + case MD_SPAN_STRONG: + break; + + case MD_SPAN_A: + break; + + case MD_SPAN_IMG: + break; + + case MD_SPAN_CODE: + break; + + default: + fprintf(stderr, "%s: Invalid span type (%d)\n", commandName, (int)type); + return 1; + break; + } + + indentLevel-=2; + printf("%*s}\n", indentLevel, ""); + return 0; } static int textHook(MD_TEXTTYPE type, const MD_CHAR * text, MD_SIZE size, void * userdata) { - printf("Text: type = %d, size=%lu, text=", (int)type, size); + switch (type) { + case MD_TEXT_NORMAL: + printf("%*sText: \"", indentLevel, ""); + break; + + case MD_TEXT_NULLCHAR: + fprintf(stderr, "%s: Null character encountered on input\n", commandName); + return 1; + + case MD_TEXT_BR: + case MD_TEXT_SOFTBR: + return 0; + + case MD_TEXT_ENTITY: + printf("%*sEntity: \"", indentLevel, ""); + break; + + case MD_TEXT_CODE: + printf("%*sCode: \"", indentLevel, ""); + break; + + default: + fprintf(stderr, "%s: Invalid text type (%d)\n", commandName, (int)type); + return 1; + break; + } + fwrite(text, sizeof(MD_CHAR), size, stdout); - putchar('\n'); + printf("\"\n"); + return 0; } @@ -108,9 +297,7 @@ static void debugLogHook(const char * message, void * userdata) int main(int argc, char * argv[]) { - static int result; - - static char * commandName; + int result; static char * inputFileName; static FILE * inputFile; @@ -119,7 +306,7 @@ int main(int argc, char * argv[]) static char * outputFileName; - printf("Stack start: %p\n", &result); + lowestStackSeen = &result; if (argc != 3) { fprintf(stderr, "USAGE: %s inputfile outputfile\n", argv[0]); @@ -172,6 +359,7 @@ int main(int argc, char * argv[]) result = md_parse(inputBuffer, inputFileLen, &parser, NULL); printf("Parser result: %d\n", result); + printf("Most stack used: %lu\n", ((unsigned long)&result) - ((unsigned long)lowestStackSeen)); return 0; }