#include #include #include "node.h" #define STRING_BUFF_SIZE 1024 static char stringBuff[STRING_BUFF_SIZE]; Node* parseHeader(TokenList** list); Node* parseCodeBlock(TokenList** list); Node* ParseNodes(TokenList* list) { printf("ParseNodes() start\n"); Node* first = NULL; TokenList* currentToken = list; Node* prevNode = NULL; printf("ParseNodes() loop\n"); while (1) { Node* currentNode = NULL; switch (currentToken->token->type) { case TT_NEWLINE: break; case TT_HASH: // start of header currentNode = parseHeader(¤tToken); break; case TT_TRIPLEBACKTICK: currentNode = parseCodeBlock(¤tToken); break; case TT_EOF: printf("EOF found\n"); return first; default: // paragraph start? break; } if (currentToken->next == NULL) { printf("currentToken->next == NULL\n"); break; } currentToken = currentToken->next; if (currentNode == NULL) continue; if (prevNode != NULL) { prevNode->next = currentNode; } if (first == NULL) { first = currentNode; } prevNode = currentNode; } return first; } Node* parseHeader(TokenList** list) { TokenList* l = *list; // Count the number of TT_HASH tokens int count = 1; while (l->next != NULL && l->next->token->type == TT_HASH) { count++; l = l->next; } if (l->next == NULL) { printf("Header missing text"); return NULL; } l = l->next; // Trim leading whitespace while (l->next != NULL && l->token->type == TT_WHITESPACE) { l = l->next; } if (l->next == NULL) { printf("Header missing text"); return NULL; } TokenList* end = l; int len = 0; // find header text size while (end->token->type != TT_NEWLINE && end->token->type != TT_EOF) { len += end->token->length; end = end->next; } char* strbuff = malloc(len+1); strbuff[0] = '\0'; while(l != end) { strncat(strbuff, l->token->literal, l->token->length); l = l->next; } *list = l; printf("header hash count: %d\ntext: '%s'\n", count, stringBuff); HeaderNode* retval = malloc(sizeof(HeaderNode)); switch(count) { case 1: retval->type = NT_Header1; break; case 2: retval->type = NT_Header2; break; case 3: retval->type = NT_Header3; break; default: retval->type = NT_Header4; break; } retval->next = NULL; retval->rawText = strbuff; return (Node*)retval; } Node* parseCodeBlock(TokenList** list) { TokenList* l = *list; // find closing ticks int tlen = 0; // number of tokens int clen = 0; // number of characters l = l->next; // skip past the opening triple backtick // skip the first newline if (l->token->type == TT_NEWLINE) { l = l->next; } while (l->next != NULL && l->next->token->type != TT_TRIPLEBACKTICK) { if (l->next->token->type == TT_EOF) { printf("premature EOF"); ErrorNode* err = malloc(sizeof(ErrorNode)); err->type = NT_Error; err->next = NULL; err->error = "premature EOF searching for closing triple backtick"; return (Node*)err; } tlen++; clen += l->token->length; l = l->next; } l = *list; printf("codeblock token length: %d\n", tlen); printf("codeblock char length: %d\n", clen); printf("malloc(%ld)\n", sizeof(char)*clen+1); char* strbuff = malloc(sizeof(char)*clen+1); strbuff[0] = '\0'; int i; l = l->next; // skip past the opening triple backtick // skip the first newline if (l->token->type == TT_NEWLINE) { l = l->next; } for(i = 0; i < tlen; i++) { strncat(strbuff, l->token->literal, l->token->length); l = l->next; } // skip past closing triple backtick *list = l->next; printf("malloc(%ld)\n", sizeof(CodeBlockNode)); CodeBlockNode* ret = malloc(sizeof(CodeBlockNode)); ret->type = NT_BlockCode; ret->rawText = strbuff; ret->next = NULL; return (Node*)ret; } char* NodeTypeString(NodeType t) { switch(t) { case NT_Header1: return "NT_Header1"; case NT_Header2: return "NT_Header2"; case NT_Header3: return "NT_Header3"; case NT_Header4: return "NT_Header4"; case NT_Paragraph: return "NT_Paragraph"; case NT_UnorderedList: return "NT_UnorderedList"; case NT_OrderedList: return "NT_OrderedList"; case NT_InlineCode: return "NT_InlineCode"; case NT_BlockCode: return "NT_BlockCode"; case NT_BlockQuote: return "NT_BlockQuote"; case NT_Bold: return "NT_Bold"; case NT_Underline: return "NT_Underline"; case NT_Error: return "NT_Error"; default: snprintf(stringBuff, 1000, "unknown NodeType: %d", t); return stringBuff; } }