aboutsummaryrefslogtreecommitdiff
path: root/src/print.c
blob: 44051e68cffcca056662620dd7f044f865d0711b (plain)
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "cmark.h"
  5. #include "buffer.h"
  6. #include "node.h"
  7. #define INDENT 2
  8. static void print_str(strbuf* buffer, const unsigned char *s, int len)
  9. {
  10. int i;
  11. if (len < 0)
  12. len = strlen((char *)s);
  13. strbuf_putc(buffer, '"');
  14. for (i = 0; i < len; ++i) {
  15. unsigned char c = s[i];
  16. switch (c) {
  17. case '\n':
  18. strbuf_printf(buffer, "\\n");
  19. break;
  20. case '"':
  21. strbuf_printf(buffer, "\\\"");
  22. break;
  23. case '\\':
  24. strbuf_printf(buffer, "\\\\");
  25. break;
  26. default:
  27. strbuf_putc(buffer, (int)c);
  28. }
  29. }
  30. strbuf_putc(buffer, '"');
  31. }
  32. // Prettyprint an inline list, for debugging.
  33. static void render_nodes(strbuf* buffer, cmark_node* node, int indent)
  34. {
  35. int i;
  36. cmark_list *data;
  37. while(node != NULL) {
  38. for (i=0; i < indent; i++) {
  39. strbuf_putc(buffer, ' ');
  40. }
  41. switch(node->type) {
  42. case NODE_DOCUMENT:
  43. render_nodes(buffer, node->first_child, 0);
  44. break;
  45. case NODE_BLOCK_QUOTE:
  46. strbuf_printf(buffer, "block_quote\n");
  47. render_nodes(buffer, node->first_child, indent + INDENT);
  48. break;
  49. case NODE_LIST_ITEM:
  50. strbuf_printf(buffer, "list_item\n");
  51. render_nodes(buffer, node->first_child, indent + INDENT);
  52. break;
  53. case NODE_LIST:
  54. data = &(node->as.list);
  55. if (data->list_type == CMARK_ORDERED_LIST) {
  56. strbuf_printf(buffer, "list (type=ordered tight=%s start=%d delim=%s)\n",
  57. (data->tight ? "true" : "false"),
  58. data->start,
  59. (data->delimiter == CMARK_PAREN_DELIM ? "parens" : "period"));
  60. } else {
  61. strbuf_printf(buffer, "list (type=bullet tight=%s bullet_char=%c)\n",
  62. (data->tight ? "true" : "false"),
  63. data->bullet_char);
  64. }
  65. render_nodes(buffer, node->first_child, indent + INDENT);
  66. break;
  67. case NODE_HEADER:
  68. strbuf_printf(buffer, "setext_header (level=%d)\n", node->as.header.level);
  69. render_nodes(buffer, node->first_child, indent + INDENT);
  70. break;
  71. case NODE_PARAGRAPH:
  72. strbuf_printf(buffer, "paragraph\n");
  73. render_nodes(buffer, node->first_child, indent + INDENT);
  74. break;
  75. case NODE_HRULE:
  76. strbuf_printf(buffer, "hrule\n");
  77. break;
  78. case NODE_CODE_BLOCK:
  79. strbuf_printf(buffer, "code block info=");
  80. print_str(buffer, node->as.code.info.ptr, -1);
  81. strbuf_putc(buffer, ' ');
  82. print_str(buffer, node->string_content.ptr, -1);
  83. strbuf_putc(buffer, '\n');
  84. break;
  85. case NODE_HTML:
  86. strbuf_printf(buffer, "html_block ");
  87. print_str(buffer, node->string_content.ptr, -1);
  88. strbuf_putc(buffer, '\n');
  89. break;
  90. case NODE_REFERENCE_DEF:
  91. // skip
  92. // strbuf_printf(buffer, "reference_def\n");
  93. break;
  94. case NODE_TEXT:
  95. strbuf_printf(buffer, "text ");
  96. print_str(buffer, node->as.literal.data, node->as.literal.len);
  97. strbuf_putc(buffer, '\n');
  98. break;
  99. case NODE_LINEBREAK:
  100. strbuf_printf(buffer, "linebreak\n");
  101. break;
  102. case NODE_SOFTBREAK:
  103. strbuf_printf(buffer, "softbreak\n");
  104. break;
  105. case NODE_INLINE_CODE:
  106. strbuf_printf(buffer, "code ");
  107. print_str(buffer, node->as.literal.data, node->as.literal.len);
  108. strbuf_putc(buffer, '\n');
  109. break;
  110. case NODE_INLINE_HTML:
  111. strbuf_printf(buffer, "html ");
  112. print_str(buffer, node->as.literal.data, node->as.literal.len);
  113. strbuf_putc(buffer, '\n');
  114. break;
  115. case NODE_LINK:
  116. case NODE_IMAGE:
  117. strbuf_printf(buffer, "%s url=", node->type == NODE_LINK ? "link" : "image");
  118. if (node->as.link.url)
  119. print_str(buffer, node->as.link.url, -1);
  120. if (node->as.link.title) {
  121. strbuf_printf(buffer, " title=");
  122. print_str(buffer, node->as.link.title, -1);
  123. }
  124. strbuf_putc(buffer, '\n');
  125. render_nodes(buffer, node->first_child, indent + INDENT);
  126. break;
  127. case NODE_STRONG:
  128. strbuf_printf(buffer, "strong\n");
  129. render_nodes(buffer, node->first_child, indent + INDENT);
  130. break;
  131. case NODE_EMPH:
  132. strbuf_printf(buffer, "emph\n");
  133. render_nodes(buffer, node->first_child, indent + INDENT);
  134. break;
  135. default:
  136. break;
  137. }
  138. node = node->next;
  139. }
  140. }
  141. void cmark_debug_print(cmark_node *root)
  142. {
  143. strbuf buffer = GH_BUF_INIT;
  144. render_nodes(&buffer, root, 0);
  145. printf("%s", buffer.ptr);
  146. }