dumptree.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* markdown: a C implementation of John Gruber's Markdown markup language.
  2. *
  3. * Copyright (C) 2007 David L Parsons.
  4. * The redistribution terms are provided in the COPYRIGHT file that must
  5. * be distributed with this source code.
  6. */
  7. #include <stdio.h>
  8. #include "markdown.h"
  9. #include "cstring.h"
  10. #include "amalloc.h"
  11. struct frame {
  12. int indent;
  13. char c;
  14. };
  15. typedef STRING(struct frame) Stack;
  16. static char *
  17. Pptype(int typ)
  18. {
  19. switch (typ) {
  20. case WHITESPACE: return "whitespace";
  21. case CODE : return "code";
  22. case QUOTE : return "quote";
  23. case MARKUP : return "markup";
  24. case HTML : return "html";
  25. case DL : return "dl";
  26. case UL : return "ul";
  27. case OL : return "ol";
  28. case LISTITEM : return "item";
  29. case HDR : return "header";
  30. case HR : return "hr";
  31. case TABLE : return "table";
  32. case SOURCE : return "source";
  33. case STYLE : return "style";
  34. default : return "mystery node!";
  35. }
  36. }
  37. static void
  38. pushpfx(int indent, char c, Stack *sp)
  39. {
  40. struct frame *q = &EXPAND(*sp);
  41. q->indent = indent;
  42. q->c = c;
  43. }
  44. static void
  45. poppfx(Stack *sp)
  46. {
  47. S(*sp)--;
  48. }
  49. static void
  50. changepfx(Stack *sp, char c)
  51. {
  52. char ch;
  53. if ( !S(*sp) ) return;
  54. ch = T(*sp)[S(*sp)-1].c;
  55. if ( ch == '+' || ch == '|' )
  56. T(*sp)[S(*sp)-1].c = c;
  57. }
  58. static void
  59. printpfx(Stack *sp, FILE *f)
  60. {
  61. int i;
  62. char c;
  63. if ( !S(*sp) ) return;
  64. c = T(*sp)[S(*sp)-1].c;
  65. if ( c == '+' || c == '-' ) {
  66. fprintf(f, "--%c", c);
  67. T(*sp)[S(*sp)-1].c = (c == '-') ? ' ' : '|';
  68. }
  69. else
  70. for ( i=0; i < S(*sp); i++ ) {
  71. if ( i )
  72. fprintf(f, " ");
  73. fprintf(f, "%*s%c", T(*sp)[i].indent + 2, " ", T(*sp)[i].c);
  74. if ( T(*sp)[i].c == '`' )
  75. T(*sp)[i].c = ' ';
  76. }
  77. fprintf(f, "--");
  78. }
  79. static void
  80. dumptree(Paragraph *pp, Stack *sp, FILE *f)
  81. {
  82. int count;
  83. Line *p;
  84. int d;
  85. static char *Begin[] = { 0, "P", "center" };
  86. while ( pp ) {
  87. if ( !pp->next )
  88. changepfx(sp, '`');
  89. printpfx(sp, f);
  90. if ( pp->typ == HDR )
  91. d += fprintf(f, "[h%d", pp->hnumber);
  92. else
  93. d = fprintf(f, "[%s", Pptype(pp->typ));
  94. if ( pp->ident )
  95. d += fprintf(f, " %s", pp->ident);
  96. if ( pp->para_flags )
  97. d += fprintf(f, " %x", pp->para_flags);
  98. if ( pp->align > 1 )
  99. d += fprintf(f, ", <%s>", Begin[pp->align]);
  100. for (count=0, p=pp->text; p; ++count, (p = p->next) )
  101. ;
  102. if ( count )
  103. d += fprintf(f, ", %d line%s", count, (count==1)?"":"s");
  104. d += fprintf(f, "]");
  105. if ( pp->down ) {
  106. pushpfx(d, pp->down->next ? '+' : '-', sp);
  107. dumptree(pp->down, sp, f);
  108. poppfx(sp);
  109. }
  110. else fputc('\n', f);
  111. pp = pp->next;
  112. }
  113. }
  114. int
  115. mkd_dump(Document *doc, FILE *out, mkd_flag_t *flags, char *title)
  116. {
  117. Stack stack;
  118. if (mkd_compile(doc, flags) ) {
  119. CREATE(stack);
  120. pushpfx(fprintf(out, "%s", title), doc->code->next ? '+' : '-', &stack);
  121. dumptree(doc->code, &stack, out);
  122. DELETE(stack);
  123. return 0;
  124. }
  125. return -1;
  126. }