// Assumes the subject has a c at the current position. static cmark_node* handle_delim(subject* subj, unsigned char c, bool smart) { int numdelims; cmark_node * inl_text; bool can_open, can_close; cmark_chunk contents; numdelims = scan_delims(subj, c, &can_open, &can_close); if (c == '\'' && smart) { contents = cmark_chunk_literal(RIGHTSINGLEQUOTE); } else if (c == '"' && smart) { contents = cmark_chunk_literal(can_close ? RIGHTDOUBLEQUOTE : LEFTDOUBLEQUOTE); } else { contents = cmark_chunk_dup(&subj->input, subj->pos - numdelims, numdelims); } inl_text = make_str(contents); if ((can_open || can_close) && (!(c == '\'' || c == '"') || smart)) { push_delimiter(subj, c, can_open, can_close, inl_text); } return inl_text; }
// Parse strong/emph or a fallback. // Assumes the subject has '_' or '*' at the current position. static cmark_node* handle_strong_emph(subject* subj, unsigned char c) { int numdelims; cmark_node * inl_text; bool can_open, can_close; numdelims = scan_delims(subj, c, &can_open, &can_close); inl_text = make_str(cmark_chunk_dup(&subj->input, subj->pos - numdelims, numdelims)); if (can_open || can_close) { push_delimiter(subj, c, can_open, can_close, inl_text); } return inl_text; }
// Parse an inline, advancing subject, and add it as a child of parent. // Return 0 if no inline can be parsed, 1 otherwise. static int parse_inline(subject* subj, cmark_node * parent, int options) { cmark_node* new_inl = NULL; cmark_chunk contents; unsigned char c; int endpos; c = peek_char(subj); if (c == 0) { return 0; } switch(c) { case '\n': new_inl = handle_newline(subj); break; case '`': new_inl = handle_backticks(subj); break; case '\\': new_inl = handle_backslash(subj); break; case '&': new_inl = handle_entity(subj); break; case '<': new_inl = handle_pointy_brace(subj); break; case '*': case '_': case '\'': case '"': new_inl = handle_delim(subj, c, options & CMARK_OPT_SMART); break; case '-': new_inl = handle_hyphen(subj, options & CMARK_OPT_SMART); break; case '.': new_inl = handle_period(subj, options & CMARK_OPT_SMART); break; case '[': advance(subj); new_inl = make_str(cmark_chunk_literal("[")); push_delimiter(subj, '[', true, false, new_inl); break; case ']': new_inl = handle_close_bracket(subj, parent); break; case '!': advance(subj); if (peek_char(subj) == '[') { advance(subj); new_inl = make_str(cmark_chunk_literal("![")); push_delimiter(subj, '!', false, true, new_inl); } else { new_inl = make_str(cmark_chunk_literal("!")); } break; default: endpos = subject_find_special_char(subj, options); contents = cmark_chunk_dup(&subj->input, subj->pos, endpos - subj->pos); subj->pos = endpos; // if we're at a newline, strip trailing spaces. if (peek_char(subj) == '\n') { cmark_chunk_rtrim(&contents); } new_inl = make_str(contents); } if (new_inl != NULL) { cmark_node_append_child(parent, new_inl); } return 1; }