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.

147 lines
2.6 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. default : return "mystery node!";
  32. }
  33. }
  34. static void
  35. pushpfx(int indent, char c, Stack *sp)
  36. {
  37. struct frame *q = &EXPAND(*sp);
  38. q->indent = indent;
  39. q->c = c;
  40. }
  41. static void
  42. poppfx(Stack *sp)
  43. {
  44. S(*sp)--;
  45. }
  46. static void
  47. changepfx(Stack *sp, char c)
  48. {
  49. char ch;
  50. if ( !S(*sp) ) return;
  51. ch = T(*sp)[S(*sp)-1].c;
  52. if ( ch == '+' || ch == '|' )
  53. T(*sp)[S(*sp)-1].c = c;
  54. }
  55. static void
  56. printpfx(Stack *sp, FILE *f)
  57. {
  58. int i;
  59. char c;
  60. if ( !S(*sp) ) return;
  61. c = T(*sp)[S(*sp)-1].c;
  62. if ( c == '+' || c == '-' ) {
  63. fprintf(f, "--%c", c);
  64. T(*sp)[S(*sp)-1].c = (c == '-') ? ' ' : '|';
  65. }
  66. else
  67. for ( i=0; i < S(*sp); i++ ) {
  68. if ( i )
  69. fprintf(f, " ");
  70. fprintf(f, "%*s%c", T(*sp)[i].indent + 2, " ", T(*sp)[i].c);
  71. if ( T(*sp)[i].c == '`' )
  72. T(*sp)[i].c = ' ';
  73. }
  74. fprintf(f, "--");
  75. }
  76. static void
  77. dumptree(Paragraph *pp, Stack *sp, FILE *f)
  78. {
  79. int count;
  80. Line *p;
  81. int d;
  82. static char *Begin[] = { 0, "P", "center" };
  83. while ( pp ) {
  84. if ( !pp->next )
  85. changepfx(sp, '`');
  86. printpfx(sp, f);
  87. d = fprintf(f, "[%s", Pptype(pp->typ));
  88. if ( pp->align )
  89. d += fprintf(f, ", <%s>", Begin[pp->align]);
  90. for (count=0, p=pp->text; p; ++count, (p = p->next) )
  91. ;
  92. if ( count )
  93. d += fprintf(f, ", %d line%s", count, (count==1)?"":"s");
  94. d += fprintf(f, "]");
  95. if ( pp->down ) {
  96. pushpfx(d, pp->down->next ? '+' : '-', sp);
  97. dumptree(pp->down, sp, f);
  98. poppfx(sp);
  99. }
  100. else fputc('\n', f);
  101. pp = pp->next;
  102. }
  103. }
  104. int
  105. mkd_dump(Document *doc, FILE *out, int flags, char *title)
  106. {
  107. Stack stack;
  108. if (mkd_compile(doc, flags) ) {
  109. CREATE(stack);
  110. pushpfx(fprintf(out, "%s", title), doc->code->next ? '+' : '-', &stack);
  111. dumptree(doc->code, &stack, out);
  112. DELETE(stack);
  113. mkd_cleanup(doc);
  114. return 0;
  115. }
  116. return -1;
  117. }