cmark

My personal build of CMark ✏️

Commit
77ea10290e75313c5faf61a70cdcb1dbc5e51813
Parent
c444f374f7c920c5bb699a6e9ad3c526d29edd9b
Author
John MacFarlane <jgm@berkeley.edu>
Date

commonmark renderer: proper numbering for ordered lists.

Diffstat

1 file changed, 29 insertions, 10 deletions

Status File Name N° Changes Insertions Deletions
Modified src/commonmark.c 39 29 10
diff --git a/src/commonmark.c b/src/commonmark.c
@@ -180,11 +180,14 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
 {
 	cmark_node *tmp;
 	int list_number;
+	cmark_delim_type list_delim;
 	int numticks;
 	int i;
 	bool entering = (ev_type == CMARK_EVENT_ENTER);
 	const char *info;
 	const char *title;
+	char listmarker[64];
+	int marker_width;
 
 	switch (node->type) {
 	case CMARK_NODE_DOCUMENT:
@@ -208,25 +211,41 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
 
 	case CMARK_NODE_ITEM:
 		// TODO implement tight lists
+		if (cmark_node_get_list_type(node->parent) ==
+		    CMARK_BULLET_LIST) {
+			marker_width = 2;
+		} else {
+			list_number = cmark_node_get_list_start(node->parent);
+			list_delim = cmark_node_get_list_delim(node->parent);
+			tmp = node;
+			while (tmp->prev) {
+				tmp = tmp->prev;
+				list_number += 1;
+			}
+			// we ensure a width of at least 4 so
+			// we get nice transition from single digits
+			// to double
+			snprintf(listmarker, 63, "%d%s%s", list_number,
+				 list_delim == CMARK_PAREN_DELIM ?
+				 ")" : ".",
+				 list_number < 10 ? "  " : " ");
+			marker_width = strlen(listmarker);
+		}
 		if (entering) {
 			if (cmark_node_get_list_type(node->parent) ==
 			    CMARK_BULLET_LIST) {
 				lit(state, "- ", false);
 				cmark_strbuf_puts(state->prefix, "  ");
 			} else {
-				list_number = cmark_node_get_list_start(node->parent);
-				tmp = node;
-				while (tmp->prev) {
-					tmp = tmp->prev;
-					list_number += 1;
+				lit(state, listmarker, false);
+				for (i=marker_width; i--;) {
+					cmark_strbuf_putc(state->prefix, ' ');
 				}
-				lit(state, "1.  ", false);
-				cmark_strbuf_puts(state->prefix, "    ");
 			}
 		} else {
-			cmark_strbuf_truncate(state->prefix, state->prefix->size -
-					      (cmark_node_get_list_type(node->parent) ==
-					       CMARK_BULLET_LIST ? 2 : 4));
+			cmark_strbuf_truncate(state->prefix,
+					      state->prefix->size -
+					      marker_width);
 			cr(state);
 		}
 		break;