markdown.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. #ifndef _MARKDOWN_D
  2. #define _MARKDOWN_D
  3. #include "config.h"
  4. #include "cstring.h"
  5. #ifdef HAVE_INTTYPES_H
  6. # include <inttypes.h>
  7. #elif HAVE_STDINT_H
  8. # include <stdint.h>
  9. #endif
  10. /* flags, captured into a named type
  11. */
  12. enum { MKD_NOLINKS=0, /* don't do link processing, block <a> tags */
  13. MKD_NOIMAGE, /* don't do image processing, block <img> */
  14. MKD_NOPANTS, /* don't run smartypants() */
  15. MKD_NOHTML, /* don't allow raw html through AT ALL */
  16. MKD_NORMAL_LISTITEM, /* disable github-style checkbox lists */
  17. MKD_TAGTEXT, /* process text inside an html tag */
  18. MKD_NO_EXT, /* don't allow pseudo-protocols */
  19. #define MKD_NOEXT MKD_NO_EXT
  20. MKD_EXPLICITLIST, /* don't combine numbered/bulletted lists */
  21. MKD_CDATA, /* generate code for xml ![CDATA[...]] */
  22. MKD_NOSUPERSCRIPT, /* no A^B */
  23. MKD_NORELAXED, /* emphasis happens /everywhere/ */
  24. MKD_NOTABLES, /* disallow tables */
  25. MKD_NOSTRIKETHROUGH, /* forbid ~~strikethrough~~ */
  26. MKD_1_COMPAT, /* compatibility with MarkdownTest_1.0 */
  27. MKD_TOC, /* do table-of-contents processing */
  28. MKD_AUTOLINK, /* make http://foo.com link even without <>s */
  29. MKD_NOHEADER, /* don't process header blocks */
  30. MKD_TABSTOP, /* expand tabs to 4 spaces */
  31. MKD_SAFELINK, /* paranoid check for link protocol */
  32. MKD_NODIVQUOTE, /* forbid >%class% blocks */
  33. MKD_NOALPHALIST, /* forbid alphabetic lists */
  34. MKD_EXTRA_FOOTNOTE, /* enable markdown extra-style footnotes */
  35. MKD_NOSTYLE, /* don't extract <style> blocks */
  36. MKD_DLDISCOUNT, /* enable discount-style definition lists */
  37. MKD_DLEXTRA, /* enable extra-style definition lists */
  38. MKD_FENCEDCODE, /* enabled fenced code blocks */
  39. MKD_IDANCHOR, /* use id= anchors for TOC links */
  40. MKD_GITHUBTAGS, /* allow dash and underscore in element names */
  41. MKD_URLENCODEDANCHOR, /* urlencode non-identifier chars instead of replacing with dots */
  42. MKD_LATEX, /* handle embedded LaTeX escapes */
  43. /* end of user flags */
  44. IS_LABEL,
  45. MKD_NR_FLAGS };
  46. typedef struct { char bit[MKD_NR_FLAGS]; } mkd_flag_t;
  47. void mkd_init_flags(mkd_flag_t *p);
  48. #define is_flag_set(flags, item) ((flags)->bit[item])
  49. #define set_mkd_flag(flags, item) ((flags)->bit[item] = 1)
  50. #define clear_mkd_flag(flags, item) ((flags)->bit[item] = 0)
  51. #define COPY_FLAGS(dst,src) memcpy(&dst,&src,sizeof dst)
  52. void ___mkd_or_flags(mkd_flag_t* dst, mkd_flag_t* src);
  53. int ___mkd_different(mkd_flag_t* dst, mkd_flag_t* src);
  54. int ___mkd_any_flags(mkd_flag_t* dst, mkd_flag_t* src);
  55. #define ADD_FLAGS(dst,src) ___mkd_or_flags(dst,src)
  56. #define DIFFERENT(dst,src) ___mkd_different(dst,src)
  57. #define ANY_FLAGS(dst,src) ___mkd_any_flags(dst,src)
  58. /* each input line is read into a Line, which contains the line,
  59. * the offset of the first non-space character [this assumes
  60. * that all tabs will be expanded to spaces!], and a pointer to
  61. * the next line.
  62. */
  63. typedef enum { chk_text, chk_code,
  64. chk_hr, chk_dash,
  65. chk_tilde, chk_backtick,
  66. chk_equal } line_type;
  67. typedef struct line {
  68. Cstring text;
  69. struct line *next;
  70. int dle; /* leading indent on the line */
  71. int line_flags; /* special attributes for this line */
  72. #define PIPECHAR 0x01 /* line contains a | */
  73. #define CHECKED 0x02
  74. line_type kind;
  75. int count;
  76. } Line;
  77. /* a paragraph is a collection of Lines, with links to the next paragraph
  78. * and (if it's a QUOTE, UL, or OL) to the reparsed contents of this
  79. * paragraph.
  80. */
  81. typedef struct paragraph {
  82. struct paragraph *next; /* next paragraph */
  83. struct paragraph *down; /* recompiled contents of this paragraph */
  84. struct line *text; /* all the text in this paragraph */
  85. char *ident; /* %id% tag for QUOTE */
  86. char *lang; /* lang attribute for CODE */
  87. enum { WHITESPACE=0, CODE, QUOTE, MARKUP,
  88. HTML, STYLE, DL, UL, OL, AL, LISTITEM,
  89. HDR, HR, TABLE, SOURCE } typ;
  90. enum { IMPLICIT=0, PARA, CENTER} align;
  91. int hnumber; /* <Hn> for typ == HDR */
  92. int para_flags;
  93. #define GITHUB_CHECK 0x01
  94. #define IS_CHECKED 0x02
  95. } Paragraph;
  96. enum { ETX, SETEXT }; /* header types */
  97. /* reference-style links (and images) are stored in an array
  98. * of footnotes.
  99. */
  100. typedef struct footnote {
  101. Cstring tag; /* the tag for the reference link */
  102. Cstring link; /* what this footnote points to */
  103. Cstring title; /* what it's called (TITLE= attribute) */
  104. Paragraph *text; /* EXTRA_FOOTNOTE content */
  105. int height, width; /* dimensions (for image link) */
  106. int dealloc; /* deallocation needed? */
  107. int refnumber;
  108. int fn_flags;
  109. #define EXTRA_FOOTNOTE 0x01
  110. #define REFERENCED 0x02
  111. } Footnote;
  112. typedef struct block {
  113. enum { bTEXT, bSTAR, bUNDER } b_type;
  114. int b_count;
  115. char b_char;
  116. Cstring b_text;
  117. Cstring b_post;
  118. } block;
  119. typedef STRING(block) Qblock;
  120. typedef char* (*mkd_callback_t)(const char*, const int, void*);
  121. typedef void (*mkd_free_t)(char*, void*);
  122. typedef struct callback_data {
  123. void *e_data; /* private data for callbacks */
  124. mkd_callback_t e_url; /* url edit callback */
  125. mkd_callback_t e_flags; /* extra href flags callback */
  126. mkd_callback_t e_anchor; /* callback for anchor types */
  127. mkd_free_t e_free; /* edit/flags callback memory deallocator */
  128. mkd_callback_t e_codefmt; /* codeblock formatter (for highlighting) */
  129. } Callback_data;
  130. struct escaped {
  131. char *text;
  132. struct escaped *up;
  133. } ;
  134. struct footnote_list {
  135. int reference;
  136. STRING(Footnote) note;
  137. } ;
  138. /* a magic markdown io thing holds all the data structures needed to
  139. * do the backend processing of a markdown document
  140. */
  141. typedef struct mmiot {
  142. Cstring out;
  143. Cstring in;
  144. Qblock Q;
  145. char last; /* last text character added to out */
  146. int isp;
  147. struct escaped *esc;
  148. char *ref_prefix;
  149. struct footnote_list *footnotes;
  150. mkd_flag_t flags;
  151. Callback_data *cb;
  152. } MMIOT;
  153. #define MKD_EOLN '\r'
  154. /*
  155. * the mkdio text input functions return a document structure,
  156. * which contains a header (retrieved from the document if
  157. * markdown was configured * with the * --enable-pandoc-header
  158. * and the document begins with a pandoc-style header) and the
  159. * root of the linked list of Lines.
  160. */
  161. typedef struct document {
  162. int magic; /* "I AM VALID" magic number */
  163. #define VALID_DOCUMENT 0x19600731
  164. Line *title;
  165. Line *author;
  166. Line *date;
  167. ANCHOR(Line) content; /* uncompiled text, not valid after compile() */
  168. Paragraph *code; /* intermediate code generated by compile() */
  169. int compiled; /* set after mkd_compile() */
  170. int dirty; /* flags or callbacks changed */
  171. int html; /* set after (internal) htmlify() */
  172. int tabstop; /* for properly expanding tabs (ick) */
  173. char *ref_prefix;
  174. MMIOT *ctx; /* backend buffers, flags, and structures */
  175. Callback_data cb; /* callback functions & private data */
  176. } Document;
  177. /*
  178. * economy FILE-type structure for pulling characters out of a
  179. * fixed-length string.
  180. */
  181. struct string_stream {
  182. const char *data; /* the unread data */
  183. int size; /* and how much is there? */
  184. } ;
  185. /*
  186. * sneakily back-define the published interface (leaving the old functions for v2 compatibility)
  187. */
  188. #define mkd_in mkd3_in
  189. #define mkd_string mkd3_string
  190. #define gfm_in gfm3_in
  191. #define gfm_string gfm3_string
  192. #define mkd_compile mkd3_compile
  193. #define mkd_dump mkd3_dump
  194. #define markdown markdown3
  195. #define mkd_line mkd3_line
  196. #define mkd_xhtmlpage mkd3_xhtmlpage
  197. #define mkd_generateline mkd3_generateline
  198. #define mkd_flags_are mkd3_flags_are
  199. /* the published interface (plus a few local functions that I need to fix)
  200. */
  201. extern int mkd_firstnonblank(Line *);
  202. extern int mkd_compile(Document *, mkd_flag_t*);
  203. extern int mkd_document(Document *, char **);
  204. extern int mkd_generatehtml(Document *, FILE *);
  205. extern int mkd_css(Document *, char **);
  206. extern int mkd_generatecss(Document *, FILE *);
  207. #define mkd_style mkd_generatecss
  208. extern int mkd_xml(char *, int , char **);
  209. extern int mkd_generatexml(char *, int, FILE *);
  210. extern void mkd_cleanup(Document *);
  211. extern int mkd_line(char *, int, char **, mkd_flag_t*);
  212. extern int mkd_generateline(char *, int, FILE*, mkd_flag_t*);
  213. #define mkd_text mkd_generateline
  214. extern void mkd_basename(Document*, char *);
  215. typedef int (*mkd_sta_function_t)(const int,const void*);
  216. extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int, MMIOT *);
  217. extern Document *mkd_in(FILE *, mkd_flag_t*);
  218. extern Document *mkd_string(const char*, int, mkd_flag_t*);
  219. extern Document *gfm_in(FILE *, mkd_flag_t*);
  220. extern Document *gfm_string(const char*,int, mkd_flag_t*);
  221. extern void mkd_initialize();
  222. extern void mkd_shlib_destructor();
  223. extern void mkd_ref_prefix(Document*, char*);
  224. /* internal resource handling functions.
  225. */
  226. extern void ___mkd_freeLine(Line *);
  227. extern void ___mkd_freeLines(Line *);
  228. extern void ___mkd_freeParagraph(Paragraph *);
  229. extern void ___mkd_freefootnote(Footnote *);
  230. extern void ___mkd_freefootnotes(MMIOT *);
  231. extern void ___mkd_initmmiot(MMIOT *, void *);
  232. extern void ___mkd_freemmiot(MMIOT *, void *);
  233. extern void ___mkd_freeLineRange(Line *, Line *);
  234. extern void ___mkd_xml(char *, int, FILE *);
  235. extern void ___mkd_reparse(char *, int, mkd_flag_t*, MMIOT*, char*);
  236. extern void ___mkd_emblock(MMIOT*);
  237. extern void ___mkd_tidy(Cstring *);
  238. extern Document *__mkd_new_Document();
  239. extern void __mkd_enqueue(Document*, Cstring *);
  240. extern void __mkd_trim_line(Line *, int);
  241. extern int __mkd_io_strget(struct string_stream *);
  242. /* utility function to do some operation and exit the current function
  243. * if it fails
  244. */
  245. #define DO_OR_DIE(op) if ( (op) == EOF ) return EOF; else 1
  246. #endif/*_MARKDOWN_D*/