Skip to content

Commit

Permalink
XML attribute formatters (#116)
Browse files Browse the repository at this point in the history
* add custom xml attr formatter

* don't allocate

Premature design optimisation.
  • Loading branch information
Ashe Connor committed Sep 24, 2018
1 parent ee94bb0 commit 169201c
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 4 deletions.
3 changes: 3 additions & 0 deletions extensions/cmark-gfm-core-extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ uint16_t cmark_gfm_extensions_get_table_columns(cmark_node *node);
CMARK_GFM_EXTENSIONS_EXPORT
uint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node);

CMARK_GFM_EXTENSIONS_EXPORT
int cmark_gfm_extensions_get_table_row_is_header(cmark_node *node);

#ifdef __cplusplus
}
#endif
Expand Down
31 changes: 27 additions & 4 deletions extensions/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ext_scanners.h"
#include "strikethrough.h"
#include "table.h"
#include "cmark-gfm-core-extensions.h"

cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,
CMARK_NODE_TABLE_CELL;
Expand Down Expand Up @@ -488,6 +489,27 @@ static void latex_render(cmark_syntax_extension *extension,
}
}

static const char *xml_attr(cmark_syntax_extension *extension,
cmark_node *node) {
if (node->type == CMARK_NODE_TABLE_CELL) {
if (cmark_gfm_extensions_get_table_row_is_header(node->parent)) {
uint8_t *alignments = get_table_alignments(node->parent->parent);
int i = 0;
cmark_node *n;
for (n = node->parent->first_child; n; n = n->next, ++i)
if (n == node)
break;
switch (alignments[i]) {
case 'l': return " align=\"left\"";
case 'c': return " align=\"center\"";
case 'r': return " align=\"right\"";
}
}
}

return NULL;
}

static void man_render(cmark_syntax_extension *extension,
cmark_renderer *renderer, cmark_node *node,
cmark_event_type ev_type, int options) {
Expand Down Expand Up @@ -685,6 +707,7 @@ cmark_syntax_extension *create_table_extension(void) {
cmark_syntax_extension_set_commonmark_render_func(self, commonmark_render);
cmark_syntax_extension_set_plaintext_render_func(self, commonmark_render);
cmark_syntax_extension_set_latex_render_func(self, latex_render);
cmark_syntax_extension_set_xml_attr_func(self, xml_attr);
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);
Expand All @@ -711,25 +734,25 @@ 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) {
int cmark_gfm_extensions_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) {
int cmark_gfm_extensions_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)
int cmark_gfm_extensions_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)
int cmark_gfm_extensions_set_table_row_is_header(cmark_node *node, int is_header)
{
if (!node || node->type != CMARK_NODE_TABLE_ROW)
return 0;
Expand Down
9 changes: 9 additions & 0 deletions src/cmark-gfm-extension_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ typedef int (*cmark_commonmark_escape_func) (cmark_syntax_extension *extension,
cmark_node *node,
int c);

typedef const char* (*cmark_xml_attr_func) (cmark_syntax_extension *extension,
cmark_node *node);

typedef void (*cmark_html_render_func) (cmark_syntax_extension *extension,
struct cmark_html_renderer *renderer,
cmark_node *node,
Expand Down Expand Up @@ -345,6 +348,12 @@ void cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extens
/** See the documentation for 'cmark_syntax_extension'
*/
CMARK_GFM_EXPORT
void cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension,
cmark_xml_attr_func func);

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

Expand Down
5 changes: 5 additions & 0 deletions src/syntax_extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ void cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extens
extension->latex_render_func = func;
}

void cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension,
cmark_xml_attr_func func) {
extension->xml_attr_func = func;
}

void cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension,
cmark_common_render_func func) {
extension->man_render_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 @@ -21,6 +21,7 @@ struct cmark_syntax_extension {
cmark_common_render_func commonmark_render_func;
cmark_common_render_func plaintext_render_func;
cmark_common_render_func latex_render_func;
cmark_xml_attr_func xml_attr_func;
cmark_common_render_func man_render_func;
cmark_html_render_func html_render_func;
cmark_html_filter_func html_filter_func;
Expand Down
7 changes: 7 additions & 0 deletions src/xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "node.h"
#include "buffer.h"
#include "houdini.h"
#include "syntax_extension.h"

#define BUFFER_SIZE 100

Expand Down Expand Up @@ -50,6 +51,12 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
cmark_strbuf_puts(xml, buffer);
}

if (node->extension && node->extension->xml_attr_func) {
const char* r = node->extension->xml_attr_func(node->extension, node);
if (r != NULL)
cmark_strbuf_puts(xml, r);
}

literal = false;

switch (node->type) {
Expand Down

0 comments on commit 169201c

Please sign in to comment.