aboutsummaryrefslogtreecommitdiff
path: root/src/ast.h
blob: 074c67e75c8bc867cd78f5b19c12ee74ba4a5215 (plain)
  1. #ifndef CMARK_AST_H
  2. #define CMARK_AST_H
  3. #include <stdio.h>
  4. #include "config.h"
  5. #include "node.h"
  6. #include "buffer.h"
  7. #include "chunk.h"
  8. #include "cmark.h"
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif
  12. #define REFMAP_SIZE 16
  13. #define MAX_LINK_LABEL_LENGTH 1000
  14. struct cmark_node_inl {
  15. cmark_inl_tag tag;
  16. union {
  17. cmark_chunk literal;
  18. struct cmark_node_inl *inlines;
  19. struct {
  20. struct cmark_node_inl *label;
  21. unsigned char *url;
  22. unsigned char *title;
  23. } linkable;
  24. } content;
  25. struct cmark_node_inl *next;
  26. };
  27. struct cmark_reference {
  28. struct cmark_reference *next;
  29. unsigned char *label;
  30. unsigned char *url;
  31. unsigned char *title;
  32. unsigned int hash;
  33. };
  34. typedef struct cmark_reference cmark_reference;
  35. struct cmark_reference_map {
  36. cmark_reference *table[REFMAP_SIZE];
  37. };
  38. typedef struct cmark_reference_map cmark_reference_map;
  39. // Types for blocks
  40. struct cmark_ListData {
  41. cmark_list_type list_type;
  42. int marker_offset;
  43. int padding;
  44. int start;
  45. cmark_delim_type delimiter;
  46. unsigned char bullet_char;
  47. bool tight;
  48. };
  49. struct cmark_FencedCodeData {
  50. int fence_length;
  51. int fence_offset;
  52. unsigned char fence_char;
  53. cmark_strbuf info;
  54. };
  55. struct cmark_node_block {
  56. cmark_block_tag tag;
  57. int start_line;
  58. int start_column;
  59. int end_line;
  60. bool open;
  61. bool last_line_blank;
  62. struct cmark_node_block* children;
  63. struct cmark_node_block* last_child;
  64. struct cmark_node_block* parent;
  65. cmark_strbuf string_content;
  66. struct cmark_node_inl* inline_content;
  67. union {
  68. struct cmark_ListData list;
  69. struct cmark_FencedCodeData code;
  70. struct {
  71. int level;
  72. } header;
  73. } as;
  74. struct cmark_node_block *next;
  75. struct cmark_node_block *prev;
  76. };
  77. struct cmark_doc_parser {
  78. struct cmark_reference_map *refmap;
  79. struct cmark_node* root;
  80. struct cmark_node* current;
  81. int line_number;
  82. cmark_strbuf *curline;
  83. };
  84. unsigned char *cmark_clean_autolink(chunk *url, int is_email);
  85. static inline cmark_node *cmark_make_link(cmark_node *label, unsigned char *url, unsigned char *title)
  86. {
  87. cmark_node* e = (cmark_node *)calloc(1, sizeof(*e));
  88. if(e != NULL) {
  89. e->type = CMARK_NODE_LINK;
  90. e->as.link.label = label;
  91. e->as.link.url = url;
  92. e->as.link.title = title;
  93. e->next = NULL;
  94. }
  95. return e;
  96. }
  97. static inline cmark_node* cmark_make_autolink(cmark_node* label, cmark_chunk url, int is_email)
  98. {
  99. return cmark_make_link(label, cmark_clean_autolink(&url, is_email), NULL);
  100. }
  101. static inline cmark_node* cmark_make_inlines(cmark_node_type t, cmark_node* contents)
  102. {
  103. cmark_node * e = (cmark_node *)calloc(1, sizeof(*e));
  104. if(e != NULL) {
  105. e->type = t;
  106. e->first_child = contents;
  107. e->next = NULL;
  108. }
  109. return e;
  110. }
  111. // Create an inline with a literal string value.
  112. static inline cmark_node* cmark_make_literal(cmark_node_type t, cmark_chunk s)
  113. {
  114. cmark_node * e = (cmark_node *)calloc(1, sizeof(*e));
  115. if(e != NULL) {
  116. e->type = t;
  117. e->as.literal = s;
  118. e->next = NULL;
  119. }
  120. return e;
  121. }
  122. // Create an inline with no value.
  123. static inline cmark_node* cmark_make_simple(cmark_node_type t)
  124. {
  125. cmark_node* e = (cmark_node *)calloc(1, sizeof(*e));
  126. if(e != NULL) {
  127. e->type = t;
  128. e->next = NULL;
  129. }
  130. return e;
  131. }
  132. // Macros for creating various kinds of simple.
  133. #define cmark_make_str(s) cmark_make_literal(CMARK_NODE_STRING, s)
  134. #define cmark_make_code(s) cmark_make_literal(CMARK_NODE_INLINE_CODE, s)
  135. #define cmark_make_raw_html(s) cmark_make_literal(CMARK_NODE_INLINE_HTML, s)
  136. #define cmark_make_linebreak() cmark_make_simple(CMARK_NODE_LINEBREAK)
  137. #define cmark_make_softbreak() cmark_make_simple(CMARK_NODE_SOFTBREAK)
  138. #define cmark_make_emph(contents) cmark_make_inlines(CMARK_NODE_EMPH, contents)
  139. #define cmark_make_strong(contents) cmark_make_inlines(CMARK_NODE_STRONG, contents)
  140. #ifndef CMARK_NO_SHORT_NAMES
  141. #define node_inl cmark_node_inl
  142. #define ListData cmark_ListData
  143. #define FencedCodeData cmark_FencedCodeData
  144. #define node_block cmark_node_block
  145. #define make_link cmark_make_link
  146. #define make_autolink cmark_make_autolink
  147. #define make_str cmark_make_str
  148. #define make_code cmark_make_code
  149. #define make_raw_html cmark_make_raw_html
  150. #define make_linebreak cmark_make_linebreak
  151. #define make_softbreak cmark_make_softbreak
  152. #define make_emph cmark_make_emph
  153. #define make_strong cmark_make_strong
  154. #define make_simple cmark_make_simple
  155. #define make_literal cmark_make_literal
  156. #define make_inlines cmark_make_inlines
  157. #endif
  158. #ifdef __cplusplus
  159. }
  160. #endif
  161. #endif