compile-html.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * This program is free software; you can redistribute it and/or
  3. * modify it under the terms of the GNU General Public License
  4. * as published by the Free Software Foundation; either version 2
  5. * of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. * Author: g0tsu
  12. * Email: g0tsu at dnmx.0rg
  13. */
  14. #include <libhighlight.h>
  15. #ifdef CONFIG_USE_HTML
  16. #include <string.h>
  17. #include <stdlib.h>
  18. #define HL_HTML_BUFFER_SIZ 12000
  19. static char * hl_node_to_class(int t) {
  20. switch (t) {
  21. case HL_NODE_TEXT:
  22. return "text";
  23. case HL_NODE_SCOPE_START:
  24. return "scope";
  25. case HL_NODE_QUOTE:
  26. return "quote";
  27. case HL_NODE_NUMBER:
  28. case HL_NODE_SYMBOL:
  29. return "symbol";
  30. case HL_NODE_FUNCTION:
  31. return "func";
  32. case HL_NODE_FUNCTION_CALL:
  33. return "call";
  34. case HL_NODE_EXPR:
  35. return "expr";
  36. case HL_NODE_TYPE:
  37. return "type";
  38. case HL_NODE_DECL:
  39. return "decl";
  40. case HL_NODE_DEFINITION:
  41. return "def";
  42. case HL_NODE_CHCOMMENT:
  43. case HL_NODE_COMMENT_START:
  44. case HL_NODE_MCOMMENT_START:
  45. return "comment";
  46. default:
  47. break;
  48. }
  49. return "t";
  50. }
  51. static size_t hl_compile_concat(char *dst, char *src, size_t off) {
  52. int i, j;
  53. for (i = off, j = 0; src[j] != '\0' && i < HL_HTML_BUFFER_SIZ; i++, j++)
  54. dst[i] = src[j];
  55. return j;
  56. }
  57. // with endup termination
  58. static size_t hl_compile_sanitize(char *dst, char *src, size_t len, char *class, int end) {
  59. int off = 0;
  60. off += hl_compile_concat(dst, "<span class=\"hl-", off);
  61. off += hl_compile_concat(dst, class, off);
  62. off += hl_compile_concat(dst, "\">", off);
  63. for (int i = 0; i < len; i++) {
  64. if (src[i] == '<') {
  65. off += hl_compile_concat(dst, "&lt;", off);
  66. continue;
  67. }
  68. if (src[i] == '>') {
  69. off += hl_compile_concat(dst, "&gt;", off);
  70. continue;
  71. }
  72. if (off < HL_HTML_BUFFER_SIZ)
  73. dst[off++] = src[i];
  74. }
  75. if (end)
  76. off += hl_compile_concat(dst, "</span>", off);
  77. return off;
  78. }
  79. static size_t hl_compile_node(hl_node *node, char *buffer) {
  80. size_t off = 0;
  81. char *class;
  82. char *tmp;
  83. /*
  84. * Convert a simple types first
  85. */
  86. switch (node->type) {
  87. case HL_NODE_SPACE:
  88. if (node->text[0] == ' ')
  89. return hl_compile_concat(buffer, "&nbsp;", 0);
  90. if (node->text[0] == '\t')
  91. return hl_compile_concat(buffer, "&nbsp;&nbsp;", 0);
  92. case HL_NODE_NEWLINE:
  93. return hl_compile_concat(buffer, "<br>\n", 0);
  94. case HL_NODE_QUOTE:
  95. case HL_NODE_TEXT:
  96. case HL_NODE_FUNCTION:
  97. case HL_NODE_FUNCTION_CALL:
  98. case HL_NODE_DEFINITION:
  99. case HL_NODE_EXPR:
  100. case HL_NODE_TYPE:
  101. case HL_NODE_DECL:
  102. case HL_NODE_CHCOMMENT:
  103. case HL_NODE_NUMBER:
  104. class = hl_node_to_class(node->type);
  105. return hl_compile_sanitize(buffer, node->text, node->text_len, class, 1);
  106. case HL_NODE_COMMENT_START:
  107. case HL_NODE_MCOMMENT_START:
  108. case HL_NODE_SCOPE_START:
  109. class = hl_node_to_class(node->type);
  110. return hl_compile_sanitize(buffer, node->text, node->text_len, class, 0);
  111. case HL_NODE_COMMENT_END:
  112. case HL_NODE_MCOMMENT_END:
  113. case HL_NODE_SCOPE_END:
  114. off = hl_compile_concat(buffer, node->text, 0);
  115. off += hl_compile_concat(buffer, "</span>", off);
  116. return off;
  117. case HL_NODE_SYMBOL:
  118. if (node->text[0] == '<') {
  119. if (node->children)
  120. node->children->type = HL_NODE_DEFINITION;
  121. return hl_compile_concat(buffer, "&lt;", 0);
  122. } else if (node->text[0] == '>') {
  123. return hl_compile_concat(buffer, "&gt;", 0);
  124. }
  125. default:
  126. break;
  127. }
  128. return hl_compile_sanitize(buffer, node->text, node->text_len, "t", 1);
  129. }
  130. char * hl_compile_html(hl_root *root) {
  131. size_t len = 0, plen;
  132. hl_node *iter = root->node->root;
  133. char *out = (char *)malloc(sizeof(char));
  134. char *buffer = (char *)malloc(sizeof(char) * HL_HTML_BUFFER_SIZ);
  135. for (size_t i = 0; i < root->size; i++) {
  136. iter = iter->children;
  137. plen = len;
  138. len += hl_compile_node(iter, buffer);
  139. out = (char *)realloc(out, len * sizeof(char) + 1);
  140. for (size_t j = plen, k = 0; j < len; j++, k++)
  141. out[j] = buffer[k];
  142. }
  143. free(buffer);
  144. out[len] = 0;
  145. return out;
  146. }
  147. #endif