compile-term.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. #include <string.h>
  16. #include <stdlib.h>
  17. #define HL_TERM_BUFFER_SIZ 12000
  18. #define BLACK_TEXT "\033[30;1m"
  19. #define RED_TEXT "\033[38;5;175m"
  20. #define RRED_TEXT "\033[38;5;176m"
  21. #define GREEN_TEXT "\033[38;5;153m"
  22. #define YELLOW_TEXT "\033[38;5;209m"
  23. #define BLUE_TEXT "\033[38;5;139m"
  24. #define MAGENTA_TEXT "\033[35;1m"
  25. #define CYAN_TEXT "\033[36;1m"
  26. #define COMMENT_TEXT "\033[38;5;8m"
  27. #define WHITE_TEXT "\033[38;5;254m"
  28. static char * hl_node_to_class(int t) {
  29. switch (t) {
  30. case HL_NODE_TEXT:
  31. /* case HL_NODE_SCOPE_START:*/
  32. case HL_NODE_QUOTE:
  33. case HL_NODE_SYMBOL:
  34. return MAGENTA_TEXT;
  35. case HL_NODE_FUNCTION:
  36. return CYAN_TEXT;
  37. case HL_NODE_FUNCTION_CALL:
  38. return BLUE_TEXT;
  39. case HL_NODE_EXPR:
  40. return YELLOW_TEXT;
  41. case HL_NODE_NUMBER:
  42. case HL_NODE_TYPE:
  43. return RRED_TEXT;
  44. case HL_NODE_DECL:
  45. return RED_TEXT;
  46. case HL_NODE_DEFINITION:
  47. return GREEN_TEXT;
  48. case HL_NODE_CHCOMMENT:
  49. case HL_NODE_COMMENT_START:
  50. case HL_NODE_MCOMMENT_START:
  51. return COMMENT_TEXT;
  52. break;
  53. default:
  54. break;
  55. }
  56. return WHITE_TEXT;
  57. }
  58. static size_t hl_compile_concat(char *dst, char *src, size_t off) {
  59. int i, j;
  60. for (i = off, j = 0; src[j] != '\0' && i < HL_TERM_BUFFER_SIZ; i++, j++)
  61. dst[i] = src[j];
  62. return j;
  63. }
  64. // with endup termination
  65. static size_t hl_compile_sanitize(char *dst, char *src, size_t len, char *class, int end) {
  66. int off = 0;
  67. off += hl_compile_concat(dst, class, off);
  68. for (int i = 0; i < len; i++) {
  69. if (src[i] == '\\') {
  70. off += hl_compile_concat(dst, "\x5c", off);
  71. continue;
  72. }
  73. if (off < HL_TERM_BUFFER_SIZ)
  74. dst[off++] = src[i];
  75. }
  76. if (end)
  77. off += hl_compile_concat(dst, "\033[0m", off);
  78. return off;
  79. }
  80. static size_t hl_compile_node(hl_node *node, char *buffer, hl_ctx *ctx) {
  81. size_t off = 0;
  82. char *class;
  83. char *tmp;
  84. switch (node->type) {
  85. /* case HL_NODE_TEXT:*/
  86. case HL_NODE_SPACE:
  87. case HL_NODE_NEWLINE:
  88. return hl_compile_concat(buffer, node->text, 0);
  89. break;
  90. case HL_NODE_CHCOMMENT:
  91. case HL_NODE_FUNCTION:
  92. case HL_NODE_FUNCTION_CALL:
  93. case HL_NODE_DEFINITION:
  94. case HL_NODE_EXPR:
  95. case HL_NODE_TYPE:
  96. case HL_NODE_QUOTE:
  97. case HL_NODE_DECL:
  98. case HL_NODE_NUMBER:
  99. if (ctx->lock)
  100. break;
  101. class = hl_node_to_class(node->type);
  102. return hl_compile_sanitize(buffer, node->text, node->text_len, class, 1);
  103. case HL_NODE_COMMENT_START:
  104. case HL_NODE_MCOMMENT_START:
  105. if (ctx->lock)
  106. break;
  107. ctx->lock = node->type;
  108. class = hl_node_to_class(node->type);
  109. return hl_compile_sanitize(buffer, node->text, node->text_len, class, 0);
  110. return off;
  111. case HL_NODE_COMMENT_END:
  112. case HL_NODE_MCOMMENT_END:
  113. /* case HL_NODE_SCOPE_END:*/
  114. ctx->lock = 0;
  115. off = hl_compile_concat(buffer, node->text, 0);
  116. off += hl_compile_concat(buffer, "\033[0m", off);
  117. return off;
  118. case HL_NODE_SYMBOL:
  119. break;
  120. default:
  121. break;
  122. }
  123. if (ctx->lock) {
  124. class = hl_node_to_class(ctx->lock);
  125. off = hl_compile_sanitize(buffer, node->text, node->text_len, class, 0);
  126. return off;
  127. } else {
  128. return hl_compile_sanitize(buffer, node->text, node->text_len, WHITE_TEXT, 1);
  129. }
  130. }
  131. char * hl_compile_term(hl_root *root) {
  132. size_t len = 0, plen;
  133. hl_node *iter = root->node->root;
  134. hl_ctx *ctx = (hl_ctx *)malloc(sizeof(*ctx));
  135. char *out = (char *)malloc(sizeof(char));
  136. char *buffer = (char *)malloc(sizeof(char) * HL_TERM_BUFFER_SIZ);
  137. for (size_t i = 0; i < root->size; i++) {
  138. iter = iter->children;
  139. plen = len;
  140. len += hl_compile_node(iter, buffer, ctx);
  141. out = (char *)realloc(out, len * sizeof(char) + 1);
  142. for (size_t j = plen, k = 0; j < len; j++, k++)
  143. out[j] = buffer[k];
  144. }
  145. free(buffer);
  146. free(ctx);
  147. out[len] = 0;
  148. return out;
  149. }