diff --git a/include/mrk/ast.h b/include/mrk/ast.h index fc7f090..ccdbd1f 100644 --- a/include/mrk/ast.h +++ b/include/mrk/ast.h @@ -13,6 +13,8 @@ typedef enum mrk_ast_node_type { mrk_ast_node_type_space, mrk_ast_node_type_link, mrk_ast_node_type_paragraph, + mrk_ast_node_type_list, + mrk_ast_node_type_list_item, } mrk_ast_node_type; typedef struct mrk_ast_node { @@ -33,6 +35,13 @@ typedef struct mrk_ast_node { size_t url_start; size_t url_end; } link; + struct { + bool ordered; + } list; + struct { + bool checkbox; + bool checked; + } list_item; } d; } mrk_ast_node; diff --git a/src/_include/mrk/parser_internal.h b/src/_include/mrk/parser_internal.h index fb22c71..0cdf026 100644 --- a/src/_include/mrk/parser_internal.h +++ b/src/_include/mrk/parser_internal.h @@ -69,4 +69,9 @@ mrk_err mrk_parser_parse_text(mrk_ast_node *out, mrk_parser *parser); */ mrk_err mrk_parser_parse_link(mrk_ast_node *out, mrk_parser *parser); +/** + * Parse one of the three list types. + */ +mrk_err mrk_parser_parse_list(mrk_ast_node *out, mrk_parser *parser); + #endif diff --git a/test/parser/specific.c b/test/parser/specific.c index c4b6182..efc697a 100644 --- a/test/parser/specific.c +++ b/test/parser/specific.c @@ -57,8 +57,50 @@ void test_parse_link() { TEST_CHECK(link_text->d.text.end == 12); } +void test_parse_unordered_list() { + const char *buf = "* element one\n* element two\n paragraph in element two"; + PARSER_OPEN(buf); + + mrk_ast_node *list; + mrk_ast_node_init(&list); + TEST_CHECK(mrk_parser_parse_list(list, parser) == mrk_err_ok); + + TEST_CHECK(list->type == mrk_ast_node_type_list); + TEST_CHECK(!list->d.list.ordered); + TEST_CHECK(list->children.len == 2); + + mrk_ast_node *child = list->children.arr[0]; + TEST_CHECK(child->type == mrk_ast_node_type_list_item); + TEST_CHECK(!child->d.list_item.checkbox); + TEST_CHECK(child->children.len == 1); + + mrk_ast_node *subchild = child->children.arr[0]; + TEST_CHECK(subchild->type == mrk_ast_node_type_text); + TEST_CHECK(subchild->d.text.start == 2); + TEST_CHECK(subchild->d.text.end == 13); + + child = list->children.arr[1]; + TEST_CHECK(child->type == mrk_ast_node_type_list_item); + TEST_CHECK(!child->d.list_item.checkbox); + TEST_CHECK(child->children.len == 2); + + subchild = child->children.arr[0]; + TEST_CHECK(subchild->type == mrk_ast_node_type_text); + TEST_CHECK(subchild->d.text.start == 16); + TEST_CHECK(subchild->d.text.end == 27); + + subchild = child->children.arr[1]; + TEST_CHECK(subchild->type == mrk_ast_node_type_paragraph); + TEST_CHECK(subchild->children.len == 1); + + TEST_CHECK(subchild->children.arr[0]->type == mrk_ast_node_type_text); + TEST_CHECK(subchild->children.arr[0]->d.text.start == 31); + TEST_CHECK(subchild->children.arr[0]->d.text.end == 55); +} + TEST_LIST = { { "parser header", test_parse_header }, { "parser link", test_parse_link }, + { "parser unordered list", test_parse_unordered_list }, { NULL, NULL } };