aboutsummaryrefslogtreecommitdiff
path: root/src/cmark.c
blob: fa9b5c8d0fd619e90aa064f2210a96039fa6224c (plain)
  1. #include <stdlib.h>
  2. #include <assert.h>
  3. #include <stdio.h>
  4. #include "node.h"
  5. #include "references.h"
  6. #include "html/houdini.h"
  7. #include "cmark.h"
  8. #include "buffer.h"
  9. #include "ast.h"
  10. unsigned char *cmark_markdown_to_html(unsigned char *text, int len)
  11. {
  12. cmark_node *blocks;
  13. unsigned char *result;
  14. blocks = cmark_parse_document(text, len);
  15. result = cmark_render_html(blocks);
  16. cmark_free_nodes(blocks);
  17. return result;
  18. }
  19. // Utility function used by cmark_free_nodes
  20. static void splice_into_list(cmark_node* e, cmark_node* children) {
  21. cmark_node * tmp;
  22. if (children) {
  23. tmp = children;
  24. // Find last child
  25. while (tmp->next) {
  26. tmp = tmp->next;
  27. }
  28. // Splice children into list
  29. tmp->next = e->next;
  30. e->next = children;
  31. }
  32. return ;
  33. }
  34. unsigned char *cmark_clean_autolink(chunk *url, int is_email)
  35. {
  36. strbuf buf = GH_BUF_INIT;
  37. chunk_trim(url);
  38. if (url->len == 0)
  39. return NULL;
  40. if (is_email)
  41. strbuf_puts(&buf, "mailto:");
  42. houdini_unescape_html_f(&buf, url->data, url->len);
  43. return strbuf_detach(&buf);
  44. }
  45. // Free a cmark_node list and any children.
  46. void cmark_free_nodes(cmark_node *e)
  47. {
  48. cmark_node *next;
  49. while (e != NULL) {
  50. strbuf_free(&e->string_content);
  51. switch (e->type){
  52. case NODE_FENCED_CODE:
  53. strbuf_free(&e->as.code.info);
  54. break;
  55. case NODE_STRING:
  56. case NODE_INLINE_HTML:
  57. case NODE_INLINE_CODE:
  58. cmark_chunk_free(&e->as.literal);
  59. break;
  60. case NODE_LINK:
  61. case NODE_IMAGE:
  62. free(e->as.link.url);
  63. free(e->as.link.title);
  64. splice_into_list(e, e->as.link.label);
  65. break;
  66. default:
  67. break;
  68. }
  69. if (e->last_child) {
  70. // Splice children into list
  71. e->last_child->next = e->next;
  72. e->next = e->first_child;
  73. }
  74. next = e->next;
  75. free(e);
  76. e = next;
  77. }
  78. }