/* * toc -- spit out a table of contents based on header blocks * * Copyright (C) 2008 Jjgod Jiang, David L Parsons * portions Copyright (C) 2011 Stefano D'Angelo * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include "config.h" #include #include #include #include "cstring.h" #include "markdown.h" #include "amalloc.h" /* write an header index */ int mkd_toc(Document *p, char **doc) { Paragraph *tp, *srcp; int last_hnumber = 0; Cstring res; int size; int first = 1; if ( !(doc && p && p->ctx) ) return -1; *doc = 0; if ( ! (p->ctx->flags & MKD_TOC) ) return 0; CREATE(res); RESERVE(res, 100); for ( tp = p->code; tp ; tp = tp->next ) { if ( tp->typ == SOURCE ) { for ( srcp = tp->down; srcp; srcp = srcp->next ) { if ( srcp->typ == HDR && srcp->text ) { while ( last_hnumber > srcp->hnumber ) { if ( (last_hnumber - srcp->hnumber) > 1 ) Csprintf(&res, "\n"); Csprintf(&res, "\n%*s\n%*s", last_hnumber-1, "", last_hnumber-1, ""); --last_hnumber; } if ( last_hnumber == srcp->hnumber ) Csprintf(&res, "\n"); else if ( (srcp->hnumber > last_hnumber) && !first ) Csprintf(&res, "\n"); while ( srcp->hnumber > last_hnumber ) { Csprintf(&res, "%*s\n%*s", last_hnumber, "", last_hnumber, ""); } if ( (size = S(res)) > 0 ) { EXPAND(res) = 0; /* HACK ALERT! HACK ALERT! HACK ALERT! */ *doc = T(res); /* we know that a T(Cstring) is a character pointer * so we can simply pick it up and carry it away, * leaving the husk of the Ctring on the stack * END HACK ALERT */ } else DELETE(res); return size; } /* write an header index */ int mkd_generatetoc(Document *p, FILE *out) { char *buf = 0; int sz = mkd_toc(p, &buf); int ret = EOF; if ( sz > 0 ) ret = fwrite(buf, 1, sz, out); if ( buf ) free(buf); return (ret == sz) ? ret : EOF; }