/* char_emphasis • single and double emphasis parsing */ static size_t char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size) { char c = data[0]; size_t ret; if (size > 2 && data[1] != c) { /* whitespace cannot follow an opening emphasis; * strikethrough only takes two characters '~~' */ if (c == '~' || isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0) return 0; return ret + 1; } if (size > 3 && data[1] == c && data[2] != c) { if (isspace(data[2]) || (ret = parse_emph2(ob, rndr, data + 2, size - 2, c)) == 0) return 0; return ret + 2; } if (size > 4 && data[1] == c && data[2] == c && data[3] != c) { if (c == '~' || isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0) return 0; return ret + 3; } return 0; }
/* char_emphasis • single and double emphasis parsing */ static size_t char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size) { char c = data[0]; size_t ret; if (size > 2 && data[1] != c) { /* whitespace cannot follow an opening emphasis */ if (data[1] == ' ' || data[1] == '\t' || data[1] == '\n' || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0) return 0; return ret + 1; } if (size > 3 && data[1] == c && data[2] != c) { if (data[2] == ' ' || data[2] == '\t' || data[2] == '\n' || (ret = parse_emph2(ob, rndr, data + 2, size - 2, c)) == 0) return 0; return ret + 2; } if (size > 4 && data[1] == c && data[2] == c && data[3] != c) { if (data[3] == ' ' || data[3] == '\t' || data[3] == '\n' || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0) return 0; return ret + 3; } return 0; }
/* finds the first closing tag, and delegates to the other emph */ static size_t parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c) { size_t i = 0, len; int r; while (i < size) { len = find_emph_char(data + i, size - i, c); if (!len) return 0; i += len; /* skip whitespace preceded symbols */ if (data[i] != c || isspace(data[i - 1])) continue; if (i + 2 < size && data[i + 1] == c && data[i + 2] == c && rndr->make.triple_emphasis) { /* triple symbol found */ struct buf *work = rndr_newbuf(rndr); parse_inline(work, rndr, data, i); r = rndr->make.triple_emphasis(ob, work, rndr->make.opaque); rndr_popbuf(rndr); return r ? i + 3 : 0; } else if (i + 1 < size && data[i + 1] == c) { /* double symbol found, handing over to emph1 */ len = parse_emph1(ob, rndr, data - 2, size + 2, c); if (!len) return 0; else return len - 2; } else { /* single symbol found, handing over to emph2 */ len = parse_emph2(ob, rndr, data - 1, size + 1, c); if (!len) return 0; else return len - 1; } } return 0; }