summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2018-08-25 16:08:13 -0700
committerJohn MacFarlane <jgm@berkeley.edu>2018-08-25 16:08:13 -0700
commit880039601d2bc4baf4e17649a02480876917d0ae (patch)
treec5723a372633b480b013447a5f0f9b56f7e51b40 /src
parent76478c79d3d13a21871bbed784f75fd5d9e8b1c2 (diff)
Code span spec changes.
These affect both parsing and writing commonmark.
Diffstat (limited to 'src')
-rw-r--r--src/commonmark.c8
-rw-r--r--src/inlines.c40
2 files changed, 44 insertions, 4 deletions
diff --git a/src/commonmark.c b/src/commonmark.c
index 95a1ae5..d701bab 100644
--- a/src/commonmark.c
+++ b/src/commonmark.c
@@ -167,6 +167,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
int list_number;
cmark_delim_type list_delim;
int numticks;
+ bool extra_spaces;
int i;
bool entering = (ev_type == CMARK_EVENT_ENTER);
const char *info, *code, *title;
@@ -363,14 +364,17 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
code = cmark_node_get_literal(node);
code_len = strlen(code);
numticks = shortest_unused_backtick_sequence(code);
+ extra_spaces = code_len == 0 ||
+ code[0] == '`' || code[code_len - 1] == '`' ||
+ code[0] == ' ' || code[code_len - 1] == ' ';
for (i = 0; i < numticks; i++) {
LIT("`");
}
- if (code_len == 0 || code[0] == '`') {
+ if (extra_spaces) {
LIT(" ");
}
OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);
- if (code_len == 0 || code[code_len - 1] == '`') {
+ if (extra_spaces) {
LIT(" ");
}
for (i = 0; i < numticks; i++) {
diff --git a/src/inlines.c b/src/inlines.c
index 8bb82f1..0dc7864 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -323,6 +323,42 @@ static bufsize_t scan_to_closing_backticks(subject *subj,
return 0;
}
+// Destructively modify string, converting newlines to
+// spaces or removing them if they're adjacent to spaces,
+// then removing a single leading + trailing space.
+static void S_normalize_code(cmark_strbuf *s) {
+ bool last_char_was_space = false;
+ bufsize_t r, w;
+
+ for (r = 0, w = 0; r < s->size; ++r) {
+ switch (s->ptr[r]) {
+ case '\r':
+ break;
+ case '\n':
+ if (!last_char_was_space && !cmark_isspace(s->ptr[r + 1])) {
+ s->ptr[w++] = ' ';
+ last_char_was_space = true;
+ } else {
+ last_char_was_space = false;
+ }
+ break;
+ default:
+ s->ptr[w++] = s->ptr[r];
+ last_char_was_space = (s->ptr[r] == ' ');
+ }
+ }
+
+ // begins and ends with space?
+ if (s->ptr[0] == ' ' && s->ptr[w - 1] == ' ') {
+ cmark_strbuf_drop(s, 1);
+ cmark_strbuf_truncate(s, w - 2);
+ } else {
+ cmark_strbuf_truncate(s, w);
+ }
+
+}
+
+
// Parse backtick code section or raw backticks, return an inline.
// Assumes that the subject has a backtick at the current position.
static cmark_node *handle_backticks(subject *subj, int options) {
@@ -338,8 +374,7 @@ static cmark_node *handle_backticks(subject *subj, int options) {
cmark_strbuf_set(&buf, subj->input.data + startpos,
endpos - startpos - openticks.len);
- cmark_strbuf_trim(&buf);
- cmark_strbuf_normalize_whitespace(&buf);
+ S_normalize_code(&buf);
cmark_node *node = make_code(subj, startpos, endpos - openticks.len - 1, cmark_chunk_buf_detach(&buf));
adjust_subj_node_newlines(subj, node, endpos - startpos, openticks.len, options);
@@ -347,6 +382,7 @@ static cmark_node *handle_backticks(subject *subj, int options) {
}
}
+
// Scan ***, **, or * and return number scanned, or 0.
// Advances position.
static int scan_delims(subject *subj, unsigned char c, bool *can_open,