Text::Markdown::Discount
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
2.8 KiB

  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. d = fprintf(f, "[%s", Pptype(pp->typ));
  91. if ( pp->ident )
  92. d += fprintf(f, " %s", pp->ident);
  93. if ( pp->align > 1 )
  94. d += fprintf(f, ", <%s>", Begin[pp->align]);
  95. for (count=0, p=pp->text; p; ++count, (p = p->next) )
  96. ;
  97. if ( count )
  98. d += fprintf(f, ", %d line%s", count, (count==1)?"":"s");
  99. d += fprintf(f, "]");
  100. if ( pp->down ) {
  101. pushpfx(d, pp->down->next ? '+' : '-', sp);
  102. dumptree(pp->down, sp, f);
  103. poppfx(sp);
  104. }
  105. else fputc('\n', f);
  106. pp = pp->next;
  107. }
  108. }
  109. int
  110. mkd_dump(Document *doc, FILE *out, int flags, char *title)
  111. {
  112. Stack stack;
  113. if (mkd_compile(doc, flags) ) {
  114. CREATE(stack);
  115. pushpfx(fprintf(out, "%s", title), doc->code->next ? '+' : '-', &stack);
  116. dumptree(doc->code, &stack, out);
  117. DELETE(stack);
  118. mkd_cleanup(doc);
  119. return 0;
  120. }
  121. return -1;
  122. }