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.

169 lines
2.9 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 <string.h>
  9. #include <stdarg.h>
  10. #include <stdlib.h>
  11. #include <time.h>
  12. #include <ctype.h>
  13. #include "config.h"
  14. #include "cstring.h"
  15. #include "markdown.h"
  16. #include "amalloc.h"
  17. /* free a (single) line
  18. */
  19. void
  20. ___mkd_freeLine(Line *ptr)
  21. {
  22. DELETE(ptr->text);
  23. free(ptr);
  24. }
  25. /* free a list of lines
  26. */
  27. void
  28. ___mkd_freeLines(Line *p)
  29. {
  30. if (p->next)
  31. ___mkd_freeLines(p->next);
  32. ___mkd_freeLine(p);
  33. }
  34. /* bye bye paragraph.
  35. */
  36. void
  37. ___mkd_freeParagraph(Paragraph *p)
  38. {
  39. if (p->next)
  40. ___mkd_freeParagraph(p->next);
  41. if (p->down)
  42. ___mkd_freeParagraph(p->down);
  43. if (p->text)
  44. ___mkd_freeLines(p->text);
  45. if (p->ident)
  46. free(p->ident);
  47. free(p);
  48. }
  49. /* bye bye footnotes.
  50. */
  51. void
  52. ___mkd_freefootnotes(MMIOT *f)
  53. {
  54. int i;
  55. if ( f->footnotes ) {
  56. for (i=0; i < S(*f->footnotes); i++) {
  57. DELETE(T(*f->footnotes)[i].tag);
  58. DELETE(T(*f->footnotes)[i].link);
  59. DELETE(T(*f->footnotes)[i].title);
  60. }
  61. DELETE(*f->footnotes);
  62. free(f->footnotes);
  63. }
  64. }
  65. /* initialize a new MMIOT
  66. */
  67. void
  68. ___mkd_initmmiot(MMIOT *f, void *footnotes)
  69. {
  70. if ( f ) {
  71. memset(f, 0, sizeof *f);
  72. CREATE(f->in);
  73. CREATE(f->out);
  74. CREATE(f->Q);
  75. if ( footnotes )
  76. f->footnotes = footnotes;
  77. else {
  78. f->footnotes = malloc(sizeof f->footnotes[0]);
  79. CREATE(*f->footnotes);
  80. }
  81. }
  82. }
  83. /* free the contents of a MMIOT, but leave the object alone.
  84. */
  85. void
  86. ___mkd_freemmiot(MMIOT *f, void *footnotes)
  87. {
  88. if ( f ) {
  89. DELETE(f->in);
  90. DELETE(f->out);
  91. DELETE(f->Q);
  92. if ( f->footnotes != footnotes )
  93. ___mkd_freefootnotes(f);
  94. memset(f, 0, sizeof *f);
  95. }
  96. }
  97. /* free lines up to an barrier.
  98. */
  99. void
  100. ___mkd_freeLineRange(Line *anchor, Line *stop)
  101. {
  102. Line *r = anchor->next;
  103. if ( r != stop ) {
  104. while ( r && (r->next != stop) )
  105. r = r->next;
  106. if ( r ) r->next = 0;
  107. ___mkd_freeLines(anchor->next);
  108. }
  109. anchor->next = 0;
  110. }
  111. /* clean up everything allocated in __mkd_compile()
  112. */
  113. void
  114. mkd_cleanup(Document *doc)
  115. {
  116. if ( doc ) {
  117. if ( doc->ctx ) {
  118. ___mkd_freemmiot(doc->ctx, 0);
  119. free(doc->ctx);
  120. }
  121. if ( doc->code) ___mkd_freeParagraph(doc->code);
  122. if ( doc->headers ) ___mkd_freeLines(doc->headers);
  123. if ( T(doc->content) ) ___mkd_freeLines(T(doc->content));
  124. memset(doc, 0, sizeof doc[0]);
  125. free(doc);
  126. }
  127. }
  128. /* write output in XML format
  129. */
  130. void
  131. ___mkd_xml(char *p, int size, FILE *out)
  132. {
  133. char c;
  134. while ( size-- > 0 ) {
  135. if ( !isascii(c = *p++) )
  136. continue;
  137. switch (c) {
  138. case '<': fputs("&lt;", out); break;
  139. case '>': fputs("&gt;", out); break;
  140. case '&': fputs("&amp;", out); break;
  141. case '"': fputs("&quot;", out); break;
  142. case '\'':fputs("&apos;", out); break;
  143. default: putc(c,out); break;
  144. }
  145. }
  146. }