summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2015-12-19 21:15:43 -0800
committerJohn MacFarlane <jgm@berkeley.edu>2015-12-19 21:18:02 -0800
commitb0a6c472f881a3e0a7b61722fb6fddbcc39e5139 (patch)
tree511cc8147fef48a302128eae05af1ff37c21d092
parent774ac507fc7e86c6fe0d7b16a3c1abaed4849fab (diff)
Changed API for CUSTOM_BLOCK and CUSTOM_INLINE.
Instead of using their `as.literal` content, we now give each custom node *two* literal fields, one to be printed on entering the node (before rendering the children, if any), the other on exiting (after rendering children). This gives us the flexibility to have custom nodes with children.
-rw-r--r--man/man3/cmark.334
-rw-r--r--src/cmark.h25
-rw-r--r--src/commonmark.c12
-rw-r--r--src/html.c10
-rw-r--r--src/latex.c6
-rw-r--r--src/man.c6
-rw-r--r--src/node.c71
-rw-r--r--src/node.h6
-rw-r--r--src/xml.c11
9 files changed, 165 insertions, 16 deletions
diff --git a/man/man3/cmark.3 b/man/man3/cmark.3
index 2f79781..9754e78 100644
--- a/man/man3/cmark.3
+++ b/man/man3/cmark.3
@@ -112,8 +112,6 @@ are nodes of type:
.IP \[bu] 2
CMARK_NODE_HTML
.IP \[bu] 2
-CMARK_NODE_CUSTOM_BLOCK
-.IP \[bu] 2
CMARK_NODE_HRULE
.IP \[bu] 2
CMARK_NODE_CODE_BLOCK
@@ -127,8 +125,6 @@ CMARK_NODE_LINEBREAK
CMARK_NODE_CODE
.IP \[bu] 2
CMARK_NODE_INLINE_HTML
-.IP \[bu] 2
-CMARK_NODE_CUSTOM_INLINE
.PP
Nodes must only be modified after an \f[C]EXIT\f[] event, or an
\f[C]ENTER\f[] event for leaf nodes.
@@ -331,6 +327,36 @@ Sets the title of a link or image \f[I]node\f[]. Returns 1 on success, 0
on failure.
.PP
+\fIconst char *\f[] \fBcmark_node_get_on_enter\f[](\fIcmark_node *node\f[])
+
+.PP
+Gets the literal "on enter" text for a custom \f[I]node\f[], or NULL if
+none.
+
+.PP
+\fIint\f[] \fBcmark_node_set_on_enter\f[](\fIcmark_node *node\f[], \fIconst char *on_enter\f[])
+
+.PP
+Sets the literal text to render "on enter" for a custom \f[I]node\f[].
+Any children of the node will be rendered after this text. Returns 1 on
+success 0 on failure.
+
+.PP
+\fIconst char *\f[] \fBcmark_node_get_on_exit\f[](\fIcmark_node *node\f[])
+
+.PP
+Gets the literal "on exit" text for a custom \f[I]node\f[], or NULL if
+none.
+
+.PP
+\fIint\f[] \fBcmark_node_set_on_exit\f[](\fIcmark_node *node\f[], \fIconst char *on_exit\f[])
+
+.PP
+Sets the literal text to render "on exit" for a custom \f[I]node\f[].
+Any children of the node will be rendered before this text. Returns 1 on
+success 0 on failure.
+
+.PP
\fIint\f[] \fBcmark_node_get_start_line\f[](\fIcmark_node *node\f[])
.PP
diff --git a/src/cmark.h b/src/cmark.h
index be5eaad..58839d3 100644
--- a/src/cmark.h
+++ b/src/cmark.h
@@ -160,7 +160,6 @@ CMARK_EXPORT cmark_node *cmark_node_last_child(cmark_node *node);
* of type:
*
* * CMARK_NODE_HTML
- * * CMARK_NODE_CUSTOM_BLOCK
* * CMARK_NODE_HRULE
* * CMARK_NODE_CODE_BLOCK
* * CMARK_NODE_TEXT
@@ -168,7 +167,6 @@ CMARK_EXPORT cmark_node *cmark_node_last_child(cmark_node *node);
* * CMARK_NODE_LINEBREAK
* * CMARK_NODE_CODE
* * CMARK_NODE_INLINE_HTML
- * * CMARK_NODE_CUSTOM_INLINE
*
* Nodes must only be modified after an `EXIT` event, or an `ENTER` event for
* leaf nodes.
@@ -319,6 +317,29 @@ CMARK_EXPORT const char *cmark_node_get_title(cmark_node *node);
*/
CMARK_EXPORT int cmark_node_set_title(cmark_node *node, const char *title);
+/** Gets the literal "on enter" text for a custom 'node', or
+ NULL if none.
+ */
+CMARK_EXPORT const char *cmark_node_get_on_enter(cmark_node *node);
+
+/** Sets the literal text to render "on enter" for a custom 'node'.
+ Any children of the node will be rendered after this text.
+ Returns 1 on success 0 on failure.
+ */
+CMARK_EXPORT int cmark_node_set_on_enter(cmark_node *node,
+ const char *on_enter);
+
+/** Gets the literal "on exit" text for a custom 'node', or
+ NULL if none.
+ */
+CMARK_EXPORT const char *cmark_node_get_on_exit(cmark_node *node);
+
+/** Sets the literal text to render "on exit" for a custom 'node'.
+ Any children of the node will be rendered before this text.
+ Returns 1 on success 0 on failure.
+ */
+CMARK_EXPORT int cmark_node_set_on_exit(cmark_node *node, const char *on_exit);
+
/** Returns the line on which 'node' begins.
*/
CMARK_EXPORT int cmark_node_get_start_line(cmark_node *node);
diff --git a/src/commonmark.c b/src/commonmark.c
index 4fbe9fd..635794c 100644
--- a/src/commonmark.c
+++ b/src/commonmark.c
@@ -280,9 +280,13 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;
case CMARK_NODE_HTML:
+ OUT(cmark_node_get_literal(node), false, LITERAL);
+ break;
+
case CMARK_NODE_CUSTOM_BLOCK:
BLANKLINE();
- OUT(cmark_node_get_literal(node), false, LITERAL);
+ OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
+ false, LITERAL);
BLANKLINE();
break;
@@ -337,10 +341,14 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;
case CMARK_NODE_INLINE_HTML:
- case CMARK_NODE_CUSTOM_INLINE:
OUT(cmark_node_get_literal(node), false, LITERAL);
break;
+ case CMARK_NODE_CUSTOM_INLINE:
+ OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
+ false, LITERAL);
+ break;
+
case CMARK_NODE_STRONG:
if (entering) {
LIT("**");
diff --git a/src/html.c b/src/html.c
index 0e4f69f..4428fa4 100644
--- a/src/html.c
+++ b/src/html.c
@@ -178,7 +178,10 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_CUSTOM_BLOCK:
cr(html);
- cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
+ cmark_strbuf_put(
+ html, (const unsigned char *)(entering ? cmark_node_get_on_enter(node)
+ : cmark_node_get_on_exit(node)),
+ node->as.literal.len);
cr(html);
break;
@@ -240,7 +243,10 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
break;
case CMARK_NODE_CUSTOM_INLINE:
- cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
+ cmark_strbuf_put(
+ html, (const unsigned char *)(entering ? cmark_node_get_on_enter(node)
+ : cmark_node_get_on_exit(node)),
+ node->as.literal.len);
break;
case CMARK_NODE_STRONG:
diff --git a/src/latex.c b/src/latex.c
index b6197ec..d0c5a9c 100644
--- a/src/latex.c
+++ b/src/latex.c
@@ -305,7 +305,8 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
case CMARK_NODE_CUSTOM_BLOCK:
CR();
- OUT(cmark_node_get_literal(node), false, LITERAL);
+ OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
+ false, LITERAL);
CR();
break;
@@ -348,7 +349,8 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;
case CMARK_NODE_CUSTOM_INLINE:
- OUT(cmark_node_get_literal(node), false, LITERAL);
+ OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
+ false, LITERAL);
break;
case CMARK_NODE_STRONG:
diff --git a/src/man.c b/src/man.c
index d8dc0bf..941a06c 100644
--- a/src/man.c
+++ b/src/man.c
@@ -144,7 +144,8 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
case CMARK_NODE_CUSTOM_BLOCK:
CR();
- OUT(cmark_node_get_literal(node), false, LITERAL);
+ OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
+ false, LITERAL);
CR();
break;
@@ -197,7 +198,8 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;
case CMARK_NODE_CUSTOM_INLINE:
- OUT(cmark_node_get_literal(node), false, LITERAL);
+ OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
+ false, LITERAL);
break;
case CMARK_NODE_STRONG:
diff --git a/src/node.c b/src/node.c
index 10cd99d..6c82a53 100644
--- a/src/node.c
+++ b/src/node.c
@@ -113,6 +113,11 @@ static void S_free_nodes(cmark_node *e) {
cmark_chunk_free(&e->as.link.url);
cmark_chunk_free(&e->as.link.title);
break;
+ case CMARK_NODE_CUSTOM_BLOCK:
+ case CMARK_NODE_CUSTOM_INLINE:
+ cmark_chunk_free(&e->as.custom.on_enter);
+ cmark_chunk_free(&e->as.custom.on_exit);
+ break;
default:
break;
}
@@ -528,6 +533,72 @@ int cmark_node_set_title(cmark_node *node, const char *title) {
return 0;
}
+const char *cmark_node_get_on_enter(cmark_node *node) {
+ if (node == NULL) {
+ return NULL;
+ }
+
+ switch (node->type) {
+ case CMARK_NODE_CUSTOM_INLINE:
+ case CMARK_NODE_CUSTOM_BLOCK:
+ return cmark_chunk_to_cstr(&node->as.custom.on_enter);
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+int cmark_node_set_on_enter(cmark_node *node, const char *on_enter) {
+ if (node == NULL) {
+ return 0;
+ }
+
+ switch (node->type) {
+ case CMARK_NODE_CUSTOM_INLINE:
+ case CMARK_NODE_CUSTOM_BLOCK:
+ cmark_chunk_set_cstr(&node->as.custom.on_enter, on_enter);
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+const char *cmark_node_get_on_exit(cmark_node *node) {
+ if (node == NULL) {
+ return NULL;
+ }
+
+ switch (node->type) {
+ case CMARK_NODE_CUSTOM_INLINE:
+ case CMARK_NODE_CUSTOM_BLOCK:
+ return cmark_chunk_to_cstr(&node->as.custom.on_exit);
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+int cmark_node_set_on_exit(cmark_node *node, const char *on_exit) {
+ if (node == NULL) {
+ return 0;
+ }
+
+ switch (node->type) {
+ case CMARK_NODE_CUSTOM_INLINE:
+ case CMARK_NODE_CUSTOM_BLOCK:
+ cmark_chunk_set_cstr(&node->as.custom.on_exit, on_exit);
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
int cmark_node_get_start_line(cmark_node *node) {
if (node == NULL) {
return 0;
diff --git a/src/node.h b/src/node.h
index 48d12df..cc93d23 100644
--- a/src/node.h
+++ b/src/node.h
@@ -42,6 +42,11 @@ typedef struct {
cmark_chunk title;
} cmark_link;
+typedef struct {
+ cmark_chunk on_enter;
+ cmark_chunk on_exit;
+} cmark_custom;
+
struct cmark_node {
struct cmark_node *next;
struct cmark_node *prev;
@@ -69,6 +74,7 @@ struct cmark_node {
cmark_code code;
cmark_header header;
cmark_link link;
+ cmark_custom custom;
int html_block_type;
} as;
};
diff --git a/src/xml.c b/src/xml.c
index 093e6ca..d603ed1 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -53,9 +53,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_TEXT:
case CMARK_NODE_CODE:
case CMARK_NODE_HTML:
- case CMARK_NODE_CUSTOM_BLOCK:
case CMARK_NODE_INLINE_HTML:
- case CMARK_NODE_CUSTOM_INLINE:
cmark_strbuf_puts(xml, ">");
escape_xml(xml, node->as.literal.data, node->as.literal.len);
cmark_strbuf_puts(xml, "</");
@@ -101,6 +99,15 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
literal = true;
break;
+ case CMARK_NODE_CUSTOM_BLOCK:
+ case CMARK_NODE_CUSTOM_INLINE:
+ cmark_strbuf_puts(xml, " on_enter=\"");
+ escape_xml(xml, node->as.custom.on_enter.data, node->as.custom.on_enter.len);
+ cmark_strbuf_putc(xml, '"');
+ cmark_strbuf_puts(xml, " on_exit=\"");
+ escape_xml(xml, node->as.custom.on_exit.data, node->as.custom.on_exit.len);
+ cmark_strbuf_putc(xml, '"');
+ break;
case CMARK_NODE_LINK:
case CMARK_NODE_IMAGE:
cmark_strbuf_puts(xml, " destination=\"");