2021-07-14 08:15:46 -07:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "node.h"
|
|
|
|
|
|
|
|
#define STRING_BUFF_SIZE 1024
|
|
|
|
|
|
|
|
static char stringBuff[STRING_BUFF_SIZE];
|
|
|
|
|
2023-10-15 17:55:12 -07:00
|
|
|
Node* parseHeader(TokenList** list);
|
|
|
|
Node* parseCodeBlock(TokenList** list);
|
2021-07-14 08:15:46 -07:00
|
|
|
|
|
|
|
NodeList*
|
|
|
|
ParseNodes(TokenList* list)
|
|
|
|
{
|
2023-10-15 15:30:59 -07:00
|
|
|
printf("ParseNodes() start\n");
|
2021-07-14 08:15:46 -07:00
|
|
|
NodeList* nl = malloc(sizeof(NodeList));
|
2023-10-15 15:30:59 -07:00
|
|
|
nl->first = NULL;
|
2021-07-14 08:15:46 -07:00
|
|
|
|
2023-10-15 15:30:59 -07:00
|
|
|
/*currentNode->next = NULL;*/
|
|
|
|
/*currentNode->node = NULL;*/
|
2021-07-14 08:15:46 -07:00
|
|
|
|
2023-10-15 15:30:59 -07:00
|
|
|
TokenList* currentToken = list;
|
|
|
|
Node* prevNode = NULL;
|
|
|
|
|
|
|
|
printf("ParseNodes() loop\n");
|
2021-07-14 08:15:46 -07:00
|
|
|
|
|
|
|
while (1) {
|
2023-10-15 15:30:59 -07:00
|
|
|
Node* currentNode = NULL;
|
|
|
|
|
|
|
|
switch (currentToken->token->type) {
|
2021-07-14 08:15:46 -07:00
|
|
|
case TT_NEWLINE:
|
|
|
|
break;
|
|
|
|
case TT_HASH:
|
|
|
|
// start of header
|
2023-10-15 17:55:12 -07:00
|
|
|
currentNode = parseHeader(¤tToken);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TT_TRIPLEBACKTICK:
|
|
|
|
currentNode = parseCodeBlock(¤tToken);
|
2021-07-14 08:15:46 -07:00
|
|
|
break;
|
2023-10-15 15:30:59 -07:00
|
|
|
|
|
|
|
case TT_EOF:
|
|
|
|
printf("EOF found\n");
|
|
|
|
return nl;
|
2023-10-15 17:55:12 -07:00
|
|
|
|
|
|
|
default: // paragraph start?
|
2021-07-14 08:15:46 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-10-15 15:30:59 -07:00
|
|
|
if (currentToken->next == NULL) {
|
|
|
|
printf("currentToken->next == NULL\n");
|
2021-07-14 08:15:46 -07:00
|
|
|
break;
|
|
|
|
}
|
2023-10-15 15:30:59 -07:00
|
|
|
|
|
|
|
currentToken = currentToken->next;
|
|
|
|
if (currentNode == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (prevNode != NULL) {
|
|
|
|
prevNode->next = currentNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nl->first == NULL) {
|
|
|
|
nl->first = currentNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
prevNode = currentNode;
|
2021-07-14 08:15:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return nl;
|
|
|
|
}
|
|
|
|
|
2023-10-15 17:55:12 -07:00
|
|
|
Node*
|
2021-07-14 08:15:46 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-10-15 17:55:12 -07:00
|
|
|
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;
|
|
|
|
}
|
2021-07-14 08:15:46 -07:00
|
|
|
|
2023-10-15 17:55:12 -07:00
|
|
|
char* strbuff = malloc(len+1);
|
|
|
|
strbuff[0] = '\0';
|
2021-07-14 08:15:46 -07:00
|
|
|
|
2023-10-15 17:55:12 -07:00
|
|
|
while(l != end) {
|
|
|
|
strncat(strbuff, l->token->literal, l->token->length);
|
2021-07-14 08:15:46 -07:00
|
|
|
l = l->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
*list = l;
|
|
|
|
printf("header hash count: %d\ntext: '%s'\n", count, stringBuff);
|
2023-10-15 15:30:59 -07:00
|
|
|
|
|
|
|
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;
|
2023-10-15 17:55:12 -07:00
|
|
|
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;
|
2023-10-15 15:30:59 -07:00
|
|
|
|
2023-10-15 17:55:12 -07:00
|
|
|
printf("malloc(%ld)\n", sizeof(CodeBlockNode));
|
|
|
|
CodeBlockNode* ret = malloc(sizeof(CodeBlockNode));
|
|
|
|
ret->type = NT_BlockCode;
|
|
|
|
ret->rawText = strbuff;
|
|
|
|
ret->next = NULL;
|
|
|
|
return (Node*)ret;
|
2023-10-15 15:30:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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";
|
2023-10-15 17:55:12 -07:00
|
|
|
case NT_Error:
|
|
|
|
return "NT_Error";
|
2023-10-15 15:30:59 -07:00
|
|
|
|
|
|
|
default:
|
|
|
|
snprintf(stringBuff, 1000, "unknown NodeType: %d", t);
|
|
|
|
return stringBuff;
|
|
|
|
}
|
2021-07-14 08:15:46 -07:00
|
|
|
}
|
|
|
|
|