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