|
|
- /* markdown: a C implementation of John Gruber's Markdown markup language.
- *
- * Copyright (C) 2007 David L Parsons.
- * The redistribution terms are provided in the COPYRIGHT file that must
- * be distributed with this source code.
- */
- #include <stdio.h>
- #include "markdown.h"
- #include "cstring.h"
- #include "amalloc.h"
-
- struct frame {
- int indent;
- char c;
- };
-
- typedef STRING(struct frame) Stack;
-
- static char *
- Pptype(int typ)
- {
- switch (typ) {
- case WHITESPACE: return "whitespace";
- case CODE : return "code";
- case QUOTE : return "quote";
- case MARKUP : return "markup";
- case HTML : return "html";
- case DL : return "dl";
- case UL : return "ul";
- case OL : return "ol";
- case LISTITEM : return "item";
- case HDR : return "header";
- case HR : return "HR";
- default : return "mystery node!";
- }
- }
-
- static void
- pushpfx(int indent, char c, Stack *sp)
- {
- struct frame *q = &EXPAND(*sp);
-
- q->indent = indent;
- q->c = c;
- }
-
-
- static void
- poppfx(Stack *sp)
- {
- S(*sp)--;
- }
-
-
- static void
- changepfx(Stack *sp, char c)
- {
- char ch;
-
- if ( !S(*sp) ) return;
-
- ch = T(*sp)[S(*sp)-1].c;
-
- if ( ch == '+' || ch == '|' )
- T(*sp)[S(*sp)-1].c = c;
- }
-
-
- static void
- printpfx(Stack *sp, FILE *f)
- {
- int i;
- char c;
-
- if ( !S(*sp) ) return;
-
- c = T(*sp)[S(*sp)-1].c;
-
- if ( c == '+' || c == '-' ) {
- fprintf(f, "--%c", c);
- T(*sp)[S(*sp)-1].c = (c == '-') ? ' ' : '|';
- }
- else
- for ( i=0; i < S(*sp); i++ ) {
- if ( i )
- fprintf(f, " ");
- fprintf(f, "%*s%c", T(*sp)[i].indent + 2, " ", T(*sp)[i].c);
- if ( T(*sp)[i].c == '`' )
- T(*sp)[i].c = ' ';
- }
- fprintf(f, "--");
- }
-
-
- static void
- dumptree(Paragraph *pp, Stack *sp, FILE *f)
- {
- int count;
- Line *p;
- int d;
- static char *Begin[] = { 0, "P", "center" };
-
- while ( pp ) {
- if ( !pp->next )
- changepfx(sp, '`');
- printpfx(sp, f);
-
- d = fprintf(f, "[%s", Pptype(pp->typ));
- if ( pp->align )
- d += fprintf(f, ", <%s>", Begin[pp->align]);
-
- for (count=0, p=pp->text; p; ++count, (p = p->next) )
- ;
-
- if ( count )
- d += fprintf(f, ", %d line%s", count, (count==1)?"":"s");
-
- d += fprintf(f, "]");
-
- if ( pp->down ) {
- pushpfx(d, pp->down->next ? '+' : '-', sp);
- dumptree(pp->down, sp, f);
- poppfx(sp);
- }
- else fputc('\n', f);
- pp = pp->next;
- }
- }
-
-
- int
- mkd_dump(Document *doc, FILE *out, int flags, char *title)
- {
- Stack stack;
-
- if (mkd_compile(doc, flags) ) {
-
- CREATE(stack);
- pushpfx(fprintf(out, "%s", title), doc->code->next ? '+' : '-', &stack);
- dumptree(doc->code, &stack, out);
- DELETE(stack);
-
- mkd_cleanup(doc);
- return 0;
- }
- return -1;
- }
|