From d55f1130acf9708de4f74556767251f8ed85e356 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Mon, 15 Jun 2015 11:28:52 -0700 Subject: inlines.c: Added utility functions to skip spaces and line endings. --- src/inlines.c | 58 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/inlines.c b/src/inlines.c index a96a479..28250e1 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -50,6 +50,12 @@ typedef struct { delimiter *last_delim; } subject; +static inline bool +S_is_line_end_char(char c) +{ + return (c == '\n' || c == '\r'); +} + static delimiter* S_insert_emph(subject *subj, delimiter *opener, delimiter *closer); @@ -191,6 +197,32 @@ static inline int is_eof(subject* subj) // Advance the subject. Doesn't check for eof. #define advance(subj) (subj)->pos += 1 +static inline bool +skip_spaces(subject *subj) +{ + bool skipped = false; + while (peek_char(subj) == ' ') { + advance(subj); + skipped = true; + } + return skipped; +} + +static inline bool +skip_line_end(subject *subj) +{ + bool seen_line_end_char = false; + if (peek_char(subj) == '\r') { + advance(subj); + seen_line_end_char = true; + } + if (peek_char(subj) == '\n') { + advance(subj); + seen_line_end_char = true; + } + return seen_line_end_char || is_eof(subj); +} + // Take characters while a predicate holds, and return a string. static inline cmark_chunk take_while(subject* subj, int (*f)(int)) { @@ -605,8 +637,7 @@ static cmark_node* handle_backslash(subject *subj) if (cmark_ispunct(nextchar)) { // only ascii symbols and newline can be escaped advance(subj); return make_str(cmark_chunk_dup(&subj->input, subj->pos - 1, 1)); - } else if (nextchar == '\r' || nextchar == '\n') { - advance(subj); + } else if (!is_eof(subj) && skip_line_end(subj)) { return make_linebreak(); } else { return make_str(cmark_chunk_literal("\\")); @@ -948,9 +979,7 @@ static cmark_node* handle_newline(subject *subj) // skip over newline advance(subj); // skip spaces at beginning of line - while (peek_char(subj) == ' ') { - advance(subj); - } + skip_spaces(subj); if (nlpos > 1 && peek_at(subj, nlpos - 1) == ' ' && peek_at(subj, nlpos - 2) == ' ') { @@ -1081,7 +1110,8 @@ static int parse_inline(subject* subj, cmark_node * parent, int options) subj->pos = endpos; // if we're at a newline, strip trailing spaces. - if (peek_char(subj) == '\r' || peek_char(subj) == '\n') { + if (peek_char(subj) == '\r' || + peek_char(subj) == '\n') { cmark_chunk_rtrim(&contents); } @@ -1108,11 +1138,9 @@ extern void cmark_parse_inlines(cmark_node* parent, cmark_reference_map *refmap, // Parse zero or more space characters, including at most one newline. static void spnl(subject* subj) { - bool seen_newline = false; - while (peek_char(subj) == ' ' || - (!seen_newline && - (seen_newline = peek_char(subj) == '\r' || peek_char(subj) == '\n'))) { - advance(subj); + skip_spaces(subj); + if (skip_line_end(subj)) { + skip_spaces(subj); } } @@ -1166,12 +1194,8 @@ bufsize_t cmark_parse_reference_inline(cmark_strbuf *input, cmark_reference_map title = cmark_chunk_literal(""); } // parse final spaces and newline: - while (peek_char(&subj) == ' ') { - advance(&subj); - } - if (peek_char(&subj) == '\r' || peek_char(&subj) == '\n') { - advance(&subj); - } else if (peek_char(&subj) != 0) { + skip_spaces(&subj); + if (!skip_line_end(&subj)) { return 0; } // insert reference into refmap -- cgit v1.2.3