aboutsummaryrefslogtreecommitdiff
path: root/src/ast.h
blob: 0640f88233b44a78fffb5a631983b15ba6a5890b (plain)
  1. #ifndef CMARK_AST_H
  2. #define CMARK_AST_H
  3. #include <stdio.h>
  4. #include "config.h"
  5. #include "buffer.h"
  6. #include "chunk.h"
  7. #include "cmark.h"
  8. #ifdef __cplusplus
  9. extern "C" {
  10. #endif
  11. #define CMARK_VERSION "0.1"
  12. #define CMARK_CODE_INDENT 4
  13. #define REFMAP_SIZE 16
  14. #define CMARK_MAX_LINK_LABEL_LENGTH 1000
  15. typedef enum {
  16. CMARK_INL_STRING,
  17. CMARK_INL_SOFTBREAK,
  18. CMARK_INL_LINEBREAK,
  19. CMARK_INL_CODE,
  20. CMARK_INL_RAW_HTML,
  21. CMARK_INL_EMPH,
  22. CMARK_INL_STRONG,
  23. CMARK_INL_LINK,
  24. CMARK_INL_IMAGE
  25. } cmark_inl_tag;
  26. struct cmark_node_inl {
  27. cmark_inl_tag tag;
  28. union {
  29. cmark_chunk literal;
  30. struct cmark_node_inl *inlines;
  31. struct {
  32. struct cmark_node_inl *label;
  33. unsigned char *url;
  34. unsigned char *title;
  35. } linkable;
  36. } content;
  37. struct cmark_node_inl *next;
  38. };
  39. struct cmark_reference {
  40. struct cmark_reference *next;
  41. unsigned char *label;
  42. unsigned char *url;
  43. unsigned char *title;
  44. unsigned int hash;
  45. };
  46. typedef struct cmark_reference cmark_reference;
  47. struct cmark_reference_map {
  48. cmark_reference *table[REFMAP_SIZE];
  49. };
  50. typedef struct cmark_reference_map cmark_reference_map;
  51. typedef enum {
  52. bullet,
  53. ordered
  54. } cmark_list_type;
  55. typedef enum {
  56. period,
  57. parens
  58. } cmark_delim_type;
  59. // Types for blocks
  60. struct cmark_ListData {
  61. cmark_list_type list_type;
  62. int marker_offset;
  63. int padding;
  64. int start;
  65. cmark_delim_type delimiter;
  66. unsigned char bullet_char;
  67. bool tight;
  68. };
  69. struct cmark_FencedCodeData {
  70. int fence_length;
  71. int fence_offset;
  72. unsigned char fence_char;
  73. cmark_strbuf info;
  74. };
  75. typedef enum {
  76. CMARK_BLOCK_DOCUMENT,
  77. CMARK_BLOCK_BQUOTE,
  78. CMARK_BLOCK_LIST,
  79. CMARK_BLOCK_LIST_ITEM,
  80. CMARK_BLOCK_FENCED_CODE,
  81. CMARK_BLOCK_INDENTED_CODE,
  82. CMARK_BLOCK_HTML,
  83. CMARK_BLOCK_PARAGRAPH,
  84. CMARK_BLOCK_ATX_HEADER,
  85. CMARK_BLOCK_SETEXT_HEADER,
  86. CMARK_BLOCK_HRULE,
  87. CMARK_BLOCK_REFERENCE_DEF
  88. } cmark_block_tag;
  89. struct cmark_node_block {
  90. cmark_block_tag tag;
  91. int start_line;
  92. int start_column;
  93. int end_line;
  94. bool open;
  95. bool last_line_blank;
  96. struct cmark_node_block* children;
  97. struct cmark_node_block* last_child;
  98. struct cmark_node_block* parent;
  99. struct cmark_node_block* top;
  100. cmark_strbuf string_content;
  101. struct cmark_node_inl* inline_content;
  102. union {
  103. struct cmark_ListData list;
  104. struct cmark_FencedCodeData code;
  105. struct {
  106. int level;
  107. } header;
  108. struct {
  109. cmark_reference_map *refmap;
  110. } document;
  111. } as;
  112. struct cmark_node_block *next;
  113. struct cmark_node_block *prev;
  114. };
  115. struct cmark_doc_parser {
  116. struct cmark_node_block* head;
  117. struct cmark_node_block* current;
  118. int line_number;
  119. cmark_strbuf *curline;
  120. };
  121. unsigned char *cmark_clean_autolink(chunk *url, int is_email);
  122. static inline cmark_node_inl *cmark_make_link(cmark_node_inl *label, unsigned char *url, unsigned char *title)
  123. {
  124. cmark_node_inl* e = (cmark_node_inl *)calloc(1, sizeof(*e));
  125. if(e != NULL) {
  126. e->tag = CMARK_INL_LINK;
  127. e->content.linkable.label = label;
  128. e->content.linkable.url = url;
  129. e->content.linkable.title = title;
  130. e->next = NULL;
  131. }
  132. return e;
  133. }
  134. static inline cmark_node_inl* cmark_make_autolink(cmark_node_inl* label, cmark_chunk url, int is_email)
  135. {
  136. return cmark_make_link(label, cmark_clean_autolink(&url, is_email), NULL);
  137. }
  138. static inline cmark_node_inl* cmark_make_inlines(cmark_inl_tag t, cmark_node_inl* contents)
  139. {
  140. cmark_node_inl * e = (cmark_node_inl *)calloc(1, sizeof(*e));
  141. if(e != NULL) {
  142. e->tag = t;
  143. e->content.inlines = contents;
  144. e->next = NULL;
  145. }
  146. return e;
  147. }
  148. // Create an inline with a literal string value.
  149. static inline cmark_node_inl* cmark_make_literal(cmark_inl_tag t, cmark_chunk s)
  150. {
  151. cmark_node_inl * e = (cmark_node_inl *)calloc(1, sizeof(*e));
  152. if(e != NULL) {
  153. e->tag = t;
  154. e->content.literal = s;
  155. e->next = NULL;
  156. }
  157. return e;
  158. }
  159. // Create an inline with no value.
  160. static inline cmark_node_inl* cmark_make_simple(cmark_inl_tag t)
  161. {
  162. cmark_node_inl* e = (cmark_node_inl *)calloc(1, sizeof(*e));
  163. if(e != NULL) {
  164. e->tag = t;
  165. e->next = NULL;
  166. }
  167. return e;
  168. }
  169. // Macros for creating various kinds of simple.
  170. #define cmark_make_str(s) cmark_make_literal(INL_STRING, s)
  171. #define cmark_make_code(s) cmark_make_literal(INL_CODE, s)
  172. #define cmark_make_raw_html(s) cmark_make_literal(INL_RAW_HTML, s)
  173. #define cmark_make_linebreak() cmark_make_simple(INL_LINEBREAK)
  174. #define cmark_make_softbreak() cmark_make_simple(INL_SOFTBREAK)
  175. #define cmark_make_emph(contents) cmark_make_inlines(INL_EMPH, contents)
  176. #define cmark_make_strong(contents) cmark_make_inlines(INL_STRONG, contents)
  177. #ifndef CMARK_NO_SHORT_NAMES
  178. #define node_inl cmark_node_inl
  179. #define INL_STRING CMARK_INL_STRING
  180. #define INL_SOFTBREAK CMARK_INL_SOFTBREAK
  181. #define INL_LINEBREAK CMARK_INL_LINEBREAK
  182. #define INL_CODE CMARK_INL_CODE
  183. #define INL_RAW_HTML CMARK_INL_RAW_HTML
  184. #define INL_EMPH CMARK_INL_EMPH
  185. #define INL_STRONG CMARK_INL_STRONG
  186. #define INL_LINK CMARK_INL_LINK
  187. #define INL_IMAGE CMARK_INL_IMAGE
  188. #define ListData cmark_ListData
  189. #define FencedCodeData cmark_FencedCodeData
  190. #define node_block cmark_node_block
  191. #define BLOCK_DOCUMENT CMARK_BLOCK_DOCUMENT
  192. #define BLOCK_BQUOTE CMARK_BLOCK_BQUOTE
  193. #define BLOCK_LIST CMARK_BLOCK_LIST
  194. #define BLOCK_LIST_ITEM CMARK_BLOCK_LIST_ITEM
  195. #define BLOCK_FENCED_CODE CMARK_BLOCK_FENCED_CODE
  196. #define BLOCK_INDENTED_CODE CMARK_BLOCK_INDENTED_CODE
  197. #define BLOCK_HTML CMARK_BLOCK_HTML
  198. #define BLOCK_PARAGRAPH CMARK_BLOCK_PARAGRAPH
  199. #define BLOCK_ATX_HEADER CMARK_BLOCK_ATX_HEADER
  200. #define BLOCK_SETEXT_HEADER CMARK_BLOCK_SETEXT_HEADER
  201. #define BLOCK_HRULE CMARK_BLOCK_HRULE
  202. #define BLOCK_REFERENCE_DEF CMARK_BLOCK_REFERENCE_DEF
  203. #define make_link cmark_make_link
  204. #define make_autolink cmark_make_autolink
  205. #define make_str cmark_make_str
  206. #define make_code cmark_make_code
  207. #define make_raw_html cmark_make_raw_html
  208. #define make_linebreak cmark_make_linebreak
  209. #define make_softbreak cmark_make_softbreak
  210. #define make_emph cmark_make_emph
  211. #define make_strong cmark_make_strong
  212. #define make_simple cmark_make_simple
  213. #define make_literal cmark_make_literal
  214. #define make_inlines cmark_make_inlines
  215. #endif
  216. #ifdef __cplusplus
  217. }
  218. #endif
  219. #endif