summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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=\"");