aboutsummaryrefslogtreecommitdiff
path: root/src/print.c
blob: ce387b4fe91d422248d0d0491f4fae85af121e2c (plain)
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "ast.h"
  5. #include "cmark.h"
  6. #include "debug.h"
  7. static void print_str(const unsigned char *s, int len)
  8. {
  9. int i;
  10. if (len < 0)
  11. len = strlen((char *)s);
  12. putchar('"');
  13. for (i = 0; i < len; ++i) {
  14. unsigned char c = s[i];
  15. switch (c) {
  16. case '\n':
  17. printf("\\n");
  18. break;
  19. case '"':
  20. printf("\\\"");
  21. break;
  22. case '\\':
  23. printf("\\\\");
  24. break;
  25. default:
  26. putchar((int)c);
  27. }
  28. }
  29. putchar('"');
  30. }
  31. // Prettyprint an inline list, for debugging.
  32. static void print_inlines(node_inl* ils, int indent)
  33. {
  34. int i;
  35. while(ils != NULL) {
  36. for (i=0; i < indent; i++) {
  37. putchar(' ');
  38. }
  39. switch(ils->tag) {
  40. case INL_STRING:
  41. printf("str ");
  42. print_str(ils->content.literal.data, ils->content.literal.len);
  43. putchar('\n');
  44. break;
  45. case INL_LINEBREAK:
  46. printf("linebreak\n");
  47. break;
  48. case INL_SOFTBREAK:
  49. printf("softbreak\n");
  50. break;
  51. case INL_CODE:
  52. printf("code ");
  53. print_str(ils->content.literal.data, ils->content.literal.len);
  54. putchar('\n');
  55. break;
  56. case INL_RAW_HTML:
  57. printf("html ");
  58. print_str(ils->content.literal.data, ils->content.literal.len);
  59. putchar('\n');
  60. break;
  61. case INL_LINK:
  62. case INL_IMAGE:
  63. printf("%s url=", ils->tag == INL_LINK ? "link" : "image");
  64. if (ils->content.linkable.url)
  65. print_str(ils->content.linkable.url, -1);
  66. if (ils->content.linkable.title) {
  67. printf(" title=");
  68. print_str(ils->content.linkable.title, -1);
  69. }
  70. putchar('\n');
  71. print_inlines(ils->content.linkable.label, indent + 2);
  72. break;
  73. case INL_STRONG:
  74. printf("strong\n");
  75. print_inlines(ils->content.linkable.label, indent + 2);
  76. break;
  77. case INL_EMPH:
  78. printf("emph\n");
  79. print_inlines(ils->content.linkable.label, indent + 2);
  80. break;
  81. }
  82. ils = ils->next;
  83. }
  84. }
  85. // Functions to pretty-print inline and node_block lists, for debugging.
  86. // Prettyprint an inline list, for debugging.
  87. static void print_blocks(node_block* b, int indent)
  88. {
  89. struct ListData *data;
  90. int i;
  91. while(b != NULL) {
  92. for (i=0; i < indent; i++) {
  93. putchar(' ');
  94. }
  95. switch(b->tag) {
  96. case BLOCK_DOCUMENT:
  97. printf("document\n");
  98. print_blocks(b->children, indent + 2);
  99. break;
  100. case BLOCK_BQUOTE:
  101. printf("block_quote\n");
  102. print_blocks(b->children, indent + 2);
  103. break;
  104. case BLOCK_LIST_ITEM:
  105. printf("list_item\n");
  106. print_blocks(b->children, indent + 2);
  107. break;
  108. case BLOCK_LIST:
  109. data = &(b->as.list);
  110. if (data->list_type == ordered) {
  111. printf("list (type=ordered tight=%s start=%d delim=%s)\n",
  112. (data->tight ? "true" : "false"),
  113. data->start,
  114. (data->delimiter == parens ? "parens" : "period"));
  115. } else {
  116. printf("list (type=bullet tight=%s bullet_char=%c)\n",
  117. (data->tight ? "true" : "false"),
  118. data->bullet_char);
  119. }
  120. print_blocks(b->children, indent + 2);
  121. break;
  122. case BLOCK_ATX_HEADER:
  123. printf("atx_header (level=%d)\n", b->as.header.level);
  124. print_inlines(b->inline_content, indent + 2);
  125. break;
  126. case BLOCK_SETEXT_HEADER:
  127. printf("setext_header (level=%d)\n", b->as.header.level);
  128. print_inlines(b->inline_content, indent + 2);
  129. break;
  130. case BLOCK_PARAGRAPH:
  131. printf("paragraph\n");
  132. print_inlines(b->inline_content, indent + 2);
  133. break;
  134. case BLOCK_HRULE:
  135. printf("hrule\n");
  136. break;
  137. case BLOCK_INDENTED_CODE:
  138. printf("indented_code ");
  139. print_str(b->string_content.ptr, -1);
  140. putchar('\n');
  141. break;
  142. case BLOCK_FENCED_CODE:
  143. printf("fenced_code length=%d info=",
  144. b->as.code.fence_length);
  145. print_str(b->as.code.info.ptr, -1);
  146. putchar(' ');
  147. print_str(b->string_content.ptr, -1);
  148. putchar('\n');
  149. break;
  150. case BLOCK_HTML:
  151. printf("html_block ");
  152. print_str(b->string_content.ptr, -1);
  153. putchar('\n');
  154. break;
  155. case BLOCK_REFERENCE_DEF:
  156. printf("reference_def\n");
  157. break;
  158. default:
  159. printf("# NOT IMPLEMENTED (%d)\n", b->tag);
  160. break;
  161. }
  162. b = b->next;
  163. }
  164. }
  165. void cmark_debug_print(node_block *root)
  166. {
  167. print_blocks(root, 0);
  168. }