/* * accumulate a blockquote. * * one sick horrible thing about blockquotes is that even though * it just takes ^> to start a quote, following lines, if quoted, * assume that the prefix is ``> ''. This means that code needs * to be indented *5* spaces from the leading '>', but *4* spaces * from the start of the line. This does not appear to be * documented in the reference implementation, but it's the * way the markdown sample web form at Daring Fireball works. */ static Line * quoteblock(Paragraph *p, DWORD flags) { Line *t, *q; int qp; for ( t = p->text; t ; t = q ) { if ( isquote(t) ) { /* clip leading spaces */ for (qp = 0; T(t->text)[qp] != '>'; qp ++) /* assert: the first nonblank character on this line * will be a > */; /* clip '>' */ qp++; /* clip next space, if any */ if ( T(t->text)[qp] == ' ' ) qp++; CLIP(t->text, 0, qp); UNCHECK(t); t->dle = mkd_firstnonblank(t); } q = skipempty(t->next); if ( (q == 0) || ((q != t->next) && (!isquote(q) || isdivmarker(q,1,flags))) ) { ___mkd_freeLineRange(t, q); t = q; break; } } if ( isdivmarker(p->text,0,flags) ) { char *prefix = "class"; int i; q = p->text; p->text = p->text->next; if ( (i = szmarkerclass(1+T(q->text))) == 3 ) /* and this would be an "%id:" prefix */ prefix="id"; if ( p->ident = malloc(4+strlen(prefix)+S(q->text)) ) sprintf(p->ident, "%s=\"%.*s\"", prefix, S(q->text)-(i+2), T(q->text)+(i+1) ); ___mkd_freeLine(q); } return t; }
static Line * headerblock(Paragraph *pp, int htyp) { Line *ret = 0; Line *p = pp->text; int i, j; switch (htyp) { case SETEXT: /* p->text is header, p->next->text is -'s or ='s */ pp->hnumber = (T(p->next->text)[0] == '=') ? 1 : 2; ret = p->next->next; ___mkd_freeLine(p->next); p->next = 0; break; case ETX: /* p->text is ###header###, so we need to trim off * the leading and trailing `#`'s */ for (i=0; (T(p->text)[i] == T(p->text)[0]) && (i < S(p->text)-1) && (i < 6); i++) ; pp->hnumber = i; while ( (i < S(p->text)) && isspace(T(p->text)[i]) ) ++i; CLIP(p->text, 0, i); UNCHECK(p); for (j=S(p->text); (j > 1) && (T(p->text)[j-1] == '#'); --j) ; while ( j && isspace(T(p->text)[j-1]) ) --j; S(p->text) = j; ret = p->next; p->next = 0; break; } return ret; }
/* * pull in a list block. A list block starts with a list marker and * runs until the next list marker, the next non-indented paragraph, * or EOF. You do not have to indent nonblank lines after the list * marker, but multiple paragraphs need to start with a 4-space indent. */ static Line * listitem(Paragraph *p, int indent, DWORD flags, linefn check) { Line *t, *q; int clip = indent; int z; for ( t = p->text; t ; t = q) { CLIP(t->text, 0, clip); UNCHECK(t); t->dle = mkd_firstnonblank(t); if ( (q = skipempty(t->next)) == 0 ) { ___mkd_freeLineRange(t,q); return 0; } /* after a blank line, the next block needs to start with a line * that's indented 4(? -- reference implementation allows a 1 * character indent, but that has unfortunate side effects here) * spaces, but after that the line doesn't need any indentation */ if ( q != t->next ) { if (q->dle < indent) { q = t->next; t->next = 0; return q; } /* indent at least 2, and at most as * as far as the initial line was indented. */ indent = clip ? clip : 2; } if ( (q->dle < indent) && (ishr(q) || islist(q,&z,flags,&z) || (check && (*check)(q))) && !issetext(q,&z) ) { q = t->next; t->next = 0; return q; } clip = (q->dle > indent) ? indent : q->dle; } return t; }