cmark

My personal build of CMark ✏️

Commit
039098095da3a31dd338f2a1137e673d914489ea
Parent
46a98104de76f0bd0b88a3c06f016e2c2b08ac18
Author
John MacFarlane <jgm@berkeley.edu>
Date

Implemented new treatment of dashes with `--smart`.

Diffstat

1 file changed, 38 insertions, 9 deletions

Status File Name N° Changes Insertions Deletions
Modified src/inlines.c 47 38 9
diff --git a/src/inlines.c b/src/inlines.c
@@ -437,18 +437,47 @@ static cmark_node* handle_delim(subject* subj, unsigned char c, bool smart)
 // Assumes we have a hyphen at the current position.
 static cmark_node* handle_hyphen(subject* subj, bool smart)
 {
+	int startpos = subj->pos;
+
 	advance(subj);
-	if (smart && peek_char(subj) == '-') {
-		advance(subj);
-		if (peek_char(subj) == '-') {
-			advance(subj);
-			return make_str(cmark_chunk_literal(EMDASH));
-		} else {
-			return make_str(cmark_chunk_literal(ENDASH));
-		}
-	} else {
+
+	if (!smart || peek_char(subj) != '-') {
 		return make_str(cmark_chunk_literal("-"));
 	}
+
+	while (smart && peek_char(subj) == '-') {
+		advance(subj);
+	}
+
+	int numhyphens = subj->pos - startpos;
+	int en_count = 0;
+	int em_count = 0;
+	int i;
+	cmark_strbuf buf = GH_BUF_INIT;
+
+	assert(numyphens > 1);
+
+	if (numhyphens % 3 == 0) { // if divisible by 3, use all em dashes
+		em_count = numhyphens / 3;
+	} else if (numhyphens % 2 == 0) { // if divisible by 2, use all en dashes
+		en_count = numhyphens / 2;
+	} else if (numhyphens % 3 == 2) { // use one en dash at end
+		en_count = 1;
+		em_count = (numhyphens - 2) / 3;
+	} else { // use two en dashes at the end
+		en_count = 2;
+		em_count = (numhyphens - 4) / 3;
+	}
+
+	for (i = em_count; i > 0; i--) {
+		cmark_strbuf_puts(&buf, EMDASH);
+	}
+
+	for (i = en_count; i > 0; i--) {
+		cmark_strbuf_puts(&buf, ENDASH);
+	}
+
+	return make_str(cmark_chunk_buf_detach(&buf));
 }
 
 // Assumes we have a period at the current position.