#include ", fp);
esc_len(fp, p + 1,
(size_t)(code_end - (p + 1)));
fputs("", fp);
p = code_end + 1;
continue;
}
}
if (*p == '[') {
link_close = strchr(p + 1, ']');
if (link_close != NULL && *(link_close + 1) == '(') {
url_start = link_close + 2;
link_end = strchr(url_start, ')');
if (link_end != NULL) {
fputs("", fp);
esc_len(fp, p + 1,
(size_t)(link_close - (p + 1)));
fputs("", fp);
p = link_end + 1;
continue;
}
}
}
n = strcspn(p, "`[");
if (n == 0) {
esc_len(fp, p, 1);
p++;
} else {
esc_len(fp, p, n);
p += n;
}
}
}
void
markdown_render(FILE *fp, const char *md,
void (*esc_len)(FILE *, const char *, size_t))
{
char *line;
char *next;
char *save;
int in_code, in_list, in_p, level;
save = md_strdup(md);
if (save == NULL)
return;
in_code = 0;
in_list = 0;
in_p = 0;
line = save;
while (line != NULL) {
next = strchr(line, '\n');
if (next != NULL) {
*next = '\0';
next++;
}
while (*line == ' ' || *line == '\t')
line++;
if (strncmp(line, "```", 3) == 0) {
if (in_p) {
fputs("
", fp);
else
fputs("\n", fp);
in_code = !in_code;
line = next;
continue;
}
if (in_code) {
esc_len(fp, line, strlen(line));
fputc('\n', fp);
line = next;
continue;
}
if (*line == '\0') {
if (in_p) {
fputs("\n", fp);
in_p = 0;
}
if (in_list) {
fputs("\n", fp);
in_list = 0;
}
line = next;
continue;
}
if (*line == '#') {
if (in_p) {
fputs("\n", fp);
in_p = 0;
}
if (in_list) {
fputs("\n", fp);
in_list = 0;
}
level = 0;
while (*line == '#' && level < 6) {
level++;
line++;
}
while (*line == ' ')
line++;
fprintf(fp, "", fp);
in_p = 1;
} else
fputs("
\n", fp);
markdown_inline(fp, line, esc_len);
line = next;
}
if (in_code)
fputs("\n", fp);
if (in_p)
fputs("