feat(ast): wrote initial ast-to-html function
parent
5c96031834
commit
8a758d3824
|
@ -6,8 +6,6 @@
|
|||
|
||||
#include "mrk/common.h"
|
||||
|
||||
#define MRK_AST_NODE_ARGS 4
|
||||
|
||||
typedef enum mrk_ast_node_type {
|
||||
mrk_ast_node_type_none = 0,
|
||||
mrk_ast_node_type_header,
|
||||
|
@ -48,4 +46,9 @@ mrk_err mrk_ast_node_init(mrk_ast_node **out);
|
|||
*/
|
||||
mrk_err mrk_ast_node_child_append(mrk_ast_node **out, mrk_ast_node *parent);
|
||||
|
||||
/**
|
||||
* Output the AST as valid HTML
|
||||
*/
|
||||
mrk_err mrk_ast_to_html(char **out, const char *orig, mrk_ast_node *root);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "mrk/ast.h"
|
||||
#include "mrk/buf.h"
|
||||
|
||||
mrk_err __mrk_ast_to_html(mrk_buf *buf, const char *orig, mrk_ast_node *root) {
|
||||
|
||||
for (size_t i = 0; i < root->children.len; i++) {
|
||||
mrk_ast_node *child = root->children.arr[i];
|
||||
|
||||
switch (child->type) {
|
||||
case mrk_ast_node_type_text:
|
||||
// TODO replace certain characters with escape sequences
|
||||
MRK_RES(mrk_buf_append_n(buf, orig + child->d.text.start,
|
||||
child->d.text.end - child->d.text.start));
|
||||
break;
|
||||
case mrk_ast_node_type_header: {
|
||||
char tag[6];
|
||||
|
||||
sprintf(tag, "<h%lu>", child->d.header.depth);
|
||||
MRK_RES(mrk_buf_append_n(buf, tag, 4));
|
||||
|
||||
MRK_RES(__mrk_ast_to_html(buf, orig, child));
|
||||
|
||||
sprintf(tag, "</h%lu>", child->d.header.depth);
|
||||
MRK_RES(mrk_buf_append_n(buf, tag, 5));
|
||||
} break;
|
||||
case mrk_ast_node_type_space:
|
||||
MRK_RES(mrk_buf_append_n(buf, " ", 1));
|
||||
break;
|
||||
case mrk_ast_node_type_link: {
|
||||
size_t url_len = child->d.link.url_end - child->d.link.url_start;
|
||||
|
||||
// <a href="[url]">
|
||||
char tag[12 + url_len];
|
||||
|
||||
sprintf(tag, "<a href=\"%.*s\">", (int)url_len,
|
||||
orig + child->d.link.url_start);
|
||||
MRK_RES(mrk_buf_append_n(buf, tag, 11 + url_len));
|
||||
|
||||
MRK_RES(__mrk_ast_to_html(buf, orig, child));
|
||||
|
||||
MRK_RES(mrk_buf_append_n(buf, "</a>", 4));
|
||||
} break;
|
||||
case mrk_ast_node_type_paragraph:
|
||||
MRK_RES(mrk_buf_append_n(buf, "<p>", 3));
|
||||
MRK_RES(__mrk_ast_to_html(buf, orig, child));
|
||||
MRK_RES(mrk_buf_append_n(buf, "</p>", 4));
|
||||
break;
|
||||
case mrk_ast_node_type_none:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mrk_err_ok;
|
||||
}
|
||||
|
||||
mrk_err mrk_ast_to_html(char **out, const char *orig, mrk_ast_node *root) {
|
||||
mrk_buf buf;
|
||||
MRK_RES(mrk_buf_init(&buf));
|
||||
|
||||
MRK_RES(__mrk_ast_to_html(&buf, orig, root));
|
||||
MRK_RES(mrk_buf_compact(&buf));
|
||||
|
||||
*out = buf.s;
|
||||
|
||||
return mrk_err_ok;
|
||||
}
|
Loading…
Reference in New Issue