Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syntax extension API: allow to create extension nodes #89

Merged
merged 1 commit into from
Sep 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions extensions/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,16 @@ static void html_render(cmark_syntax_extension *extension,
}
}

static void opaque_alloc(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {
if (node->type == CMARK_NODE_TABLE) {
node->as.opaque = mem->calloc(1, sizeof(node_table));
} else if (node->type == CMARK_NODE_TABLE_ROW) {
node->as.opaque = mem->calloc(1, sizeof(node_table_row));
} else if (node->type == CMARK_NODE_TABLE_CELL) {
node->as.opaque = mem->calloc(1, sizeof(node_cell));
}
}

static void opaque_free(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {
if (node->type == CMARK_NODE_TABLE) {
free_node_table(mem, node->as.opaque);
Expand Down Expand Up @@ -677,6 +687,7 @@ cmark_syntax_extension *create_table_extension(void) {
cmark_syntax_extension_set_latex_render_func(self, latex_render);
cmark_syntax_extension_set_man_render_func(self, man_render);
cmark_syntax_extension_set_html_render_func(self, html_render);
cmark_syntax_extension_set_opaque_alloc_func(self, opaque_alloc);
cmark_syntax_extension_set_opaque_free_func(self, opaque_free);
cmark_syntax_extension_set_commonmark_escape_func(self, escape);
CMARK_NODE_TABLE = cmark_syntax_extension_add_node(0);
Expand All @@ -699,3 +710,30 @@ uint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node) {

return ((node_table *)node->as.opaque)->alignments;
}

int cmarkextensions_set_table_columns(cmark_node *node, uint16_t n_columns) {
return set_n_table_columns(node, n_columns);
}

int cmarkextensions_set_table_alignments(cmark_node *node, uint16_t ncols, uint8_t *alignments) {
uint8_t *a = (uint8_t *)cmark_node_mem(node)->calloc(1, ncols);
memcpy(a, alignments, ncols);
return set_table_alignments(node, a);
}

int cmarkextensions_get_table_row_is_header(cmark_node *node)
{
if (!node || node->type != CMARK_NODE_TABLE_ROW)
return 0;

return ((node_table_row *)node->as.opaque)->is_header;
}

int cmarkextensions_set_table_row_is_header(cmark_node *node, int is_header)
{
if (!node || node->type != CMARK_NODE_TABLE_ROW)
return 0;

((node_table_row *)node->as.opaque)->is_header = (is_header != 0);
return 1;
}
12 changes: 10 additions & 2 deletions src/cmark-gfm-extension_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ typedef struct cmark_plugin cmark_plugin;
* with 'cmark_syntax_extension_set_private',
* and optionally define a free function for this data.
*/
typedef struct cmark_syntax_extension cmark_syntax_extension;

typedef struct subject cmark_inline_parser;

/** Exposed raw for now */
Expand Down Expand Up @@ -254,6 +252,10 @@ typedef cmark_node *(*cmark_postprocess_func) (cmark_syntax_extension *extension

typedef int (*cmark_ispunct_func) (char c);

typedef void (*cmark_opaque_alloc_func) (cmark_syntax_extension *extension,
cmark_mem *mem,
cmark_node *node);

typedef void (*cmark_opaque_free_func) (cmark_syntax_extension *extension,
cmark_mem *mem,
cmark_node *node);
Expand Down Expand Up @@ -382,6 +384,12 @@ CMARK_GFM_EXPORT
void cmark_syntax_extension_set_postprocess_func(cmark_syntax_extension *extension,
cmark_postprocess_func func);

/** See the documentation for 'cmark_syntax_extension'
*/
CMARK_GFM_EXPORT
void cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension,
cmark_opaque_alloc_func func);

/** See the documentation for 'cmark_syntax_extension'
*/
CMARK_GFM_EXPORT
Expand Down
8 changes: 8 additions & 0 deletions src/cmark-gfm.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ typedef enum {
typedef struct cmark_node cmark_node;
typedef struct cmark_parser cmark_parser;
typedef struct cmark_iter cmark_iter;
typedef struct cmark_syntax_extension cmark_syntax_extension;

/**
* ## Custom memory allocator support
Expand Down Expand Up @@ -187,6 +188,13 @@ CMARK_GFM_EXPORT cmark_node *cmark_node_new(cmark_node_type type);
CMARK_GFM_EXPORT cmark_node *cmark_node_new_with_mem(cmark_node_type type,
cmark_mem *mem);

CMARK_GFM_EXPORT cmark_node *cmark_node_new_with_ext(cmark_node_type type,
cmark_syntax_extension *extension);

CMARK_GFM_EXPORT cmark_node *cmark_node_new_with_mem_and_ext(cmark_node_type type,
cmark_mem *mem,
cmark_syntax_extension *extension);

/** Frees the memory allocated for a node and any children.
*/
CMARK_GFM_EXPORT void cmark_node_free(cmark_node *node);
Expand Down
20 changes: 17 additions & 3 deletions src/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@ static bool S_can_contain(cmark_node *node, cmark_node *child) {
return cmark_node_can_contain_type(node, (cmark_node_type) child->type);
}

cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
cmark_node *cmark_node_new_with_mem_and_ext(cmark_node_type type, cmark_mem *mem, cmark_syntax_extension *extension) {
cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node));
cmark_strbuf_init(mem, &node->content, 0);
node->type = (uint16_t)type;
node->extension = extension;

switch (node->type) {
case CMARK_NODE_HEADING:
Expand All @@ -91,12 +92,25 @@ cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
break;
}

if (node->extension && node->extension->opaque_alloc_func) {
node->extension->opaque_alloc_func(node->extension, mem, node);
}

return node;
}

cmark_node *cmark_node_new(cmark_node_type type) {
cmark_node *cmark_node_new_with_ext(cmark_node_type type, cmark_syntax_extension *extension) {
extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;
return cmark_node_new_with_mem(type, &CMARK_DEFAULT_MEM_ALLOCATOR);
return cmark_node_new_with_mem_and_ext(type, &CMARK_DEFAULT_MEM_ALLOCATOR, extension);
}

cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem)
{
return cmark_node_new_with_mem_and_ext(type, mem, NULL);
}

cmark_node *cmark_node_new(cmark_node_type type) {
return cmark_node_new_with_ext(type, NULL);
}

static void free_node_as(cmark_node *node) {
Expand Down
5 changes: 5 additions & 0 deletions src/syntax_extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ void *cmark_syntax_extension_get_private(cmark_syntax_extension *extension) {
return extension->priv;
}

void cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension,
cmark_opaque_alloc_func func) {
extension->opaque_alloc_func = func;
}

void cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extension,
cmark_opaque_free_func func) {
extension->opaque_free_func = func;
Expand Down
1 change: 1 addition & 0 deletions src/syntax_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct cmark_syntax_extension {
cmark_html_render_func html_render_func;
cmark_html_filter_func html_filter_func;
cmark_postprocess_func postprocess_func;
cmark_opaque_alloc_func opaque_alloc_func;
cmark_opaque_free_func opaque_free_func;
cmark_commonmark_escape_func commonmark_escape_func;
};
Expand Down