File indexing completed on 2024-04-28 11:21:07
0001 /* markdown: a C implementation of John Gruber's Markdown markup language. 0002 * 0003 * Copyright (C) 2007 David L Parsons. 0004 * The redistribution terms are provided in the COPYRIGHT file that must 0005 * be distributed with this source code. 0006 */ 0007 #include <stdio.h> 0008 #include "markdown.h" 0009 #include "cstring.h" 0010 #include "amalloc.h" 0011 0012 struct frame { 0013 int indent; 0014 char c; 0015 }; 0016 0017 typedef STRING(struct frame) Stack; 0018 0019 static char * 0020 Pptype(int typ) 0021 { 0022 switch (typ) { 0023 case WHITESPACE: return "whitespace"; 0024 case CODE : return "code"; 0025 case QUOTE : return "quote"; 0026 case MARKUP : return "markup"; 0027 case HTML : return "html"; 0028 case DL : return "dl"; 0029 case UL : return "ul"; 0030 case OL : return "ol"; 0031 case LISTITEM : return "item"; 0032 case HDR : return "header"; 0033 case HR : return "hr"; 0034 case TABLE : return "table"; 0035 case SOURCE : return "source"; 0036 case STYLE : return "style"; 0037 default : return "mystery node!"; 0038 } 0039 } 0040 0041 static void 0042 pushpfx(int indent, char c, Stack *sp) 0043 { 0044 struct frame *q = &EXPAND(*sp); 0045 0046 q->indent = indent; 0047 q->c = c; 0048 } 0049 0050 0051 static void 0052 poppfx(Stack *sp) 0053 { 0054 S(*sp)--; 0055 } 0056 0057 0058 static void 0059 changepfx(Stack *sp, char c) 0060 { 0061 char ch; 0062 0063 if ( !S(*sp) ) return; 0064 0065 ch = T(*sp)[S(*sp)-1].c; 0066 0067 if ( ch == '+' || ch == '|' ) 0068 T(*sp)[S(*sp)-1].c = c; 0069 } 0070 0071 0072 static void 0073 printpfx(Stack *sp, FILE *f) 0074 { 0075 int i; 0076 char c; 0077 0078 if ( !S(*sp) ) return; 0079 0080 c = T(*sp)[S(*sp)-1].c; 0081 0082 if ( c == '+' || c == '-' ) { 0083 fprintf(f, "--%c", c); 0084 T(*sp)[S(*sp)-1].c = (c == '-') ? ' ' : '|'; 0085 } 0086 else 0087 for ( i=0; i < S(*sp); i++ ) { 0088 if ( i ) 0089 fprintf(f, " "); 0090 fprintf(f, "%*s%c", T(*sp)[i].indent + 2, " ", T(*sp)[i].c); 0091 if ( T(*sp)[i].c == '`' ) 0092 T(*sp)[i].c = ' '; 0093 } 0094 fprintf(f, "--"); 0095 } 0096 0097 0098 static void 0099 dumptree(Paragraph *pp, Stack *sp, FILE *f) 0100 { 0101 int count; 0102 Line *p; 0103 int d; 0104 static char *Begin[] = { 0, "P", "center" }; 0105 0106 while ( pp ) { 0107 if ( !pp->next ) 0108 changepfx(sp, '`'); 0109 printpfx(sp, f); 0110 0111 if ( pp->typ == HDR ) 0112 d += fprintf(f, "[h%d", pp->hnumber); 0113 else 0114 d = fprintf(f, "[%s", Pptype(pp->typ)); 0115 if ( pp->ident ) 0116 d += fprintf(f, " %s", pp->ident); 0117 0118 #ifdef GITHUB_CHECKBOX 0119 if ( pp->flags ) 0120 d += fprintf(f, " %x", pp->flags); 0121 #endif 0122 0123 if ( pp->align > 1 ) 0124 d += fprintf(f, ", <%s>", Begin[pp->align]); 0125 0126 for (count=0, p=pp->text; p; ++count, (p = p->next) ) 0127 ; 0128 0129 if ( count ) 0130 d += fprintf(f, ", %d line%s", count, (count==1)?"":"s"); 0131 0132 d += fprintf(f, "]"); 0133 0134 if ( pp->down ) { 0135 pushpfx(d, pp->down->next ? '+' : '-', sp); 0136 dumptree(pp->down, sp, f); 0137 poppfx(sp); 0138 } 0139 else fputc('\n', f); 0140 pp = pp->next; 0141 } 0142 } 0143 0144 0145 int 0146 mkd_dump(Document *doc, FILE *out, mkd_flag_t flags, char *title) 0147 { 0148 Stack stack; 0149 0150 if (mkd_compile(doc, flags) ) { 0151 0152 CREATE(stack); 0153 pushpfx(fprintf(out, "%s", title), doc->code->next ? '+' : '-', &stack); 0154 dumptree(doc->code, &stack, out); 0155 DELETE(stack); 0156 0157 return 0; 0158 } 0159 return -1; 0160 }