{
"extension": ".h",
"source": "// Written by retoor@molodetz.nl\n\n// This program provides functionality to highlight keywords in source code with ANSI color formatting and to convert Markdown syntax into ANSI-colored text output.\n\n// Uses standard C libraries: <stdio.h>, <string.h>. Also utilizes ANSI escape codes for text formatting.\n\n// MIT License:\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#include <stdio.h>\n#include <string.h>\n#include <stdbool.h>\n\n#define RESET \"\\033[0m\"\n#define BOLD \"\\033[1m\"\n#define ITALIC \"\\033[3m\"\n#define FG_YELLOW \"\\033[33m\"\n#define FG_BLUE \"\\033[34m\"\n#define FG_CYAN \"\\033[36m\"\n\nint is_keyword(const char *word) {\n const char *keywords[] = {\"int\", \"float\", \"double\", \"char\", \"void\", \"if\", \"else\", \"while\", \"for\", \"return\", \"struct\", \"printf\"};\n for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {\n if (strcmp(word, keywords[i]) == 0) {\n return 1;\n }\n }\n return 0;\n}\n\nvoid highlight_code(const char *code) {\n const char *ptr = code;\n char buffer[256];\n size_t index = 0;\n\n while (*ptr) {\n if ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') || (*ptr == '_')) {\n while ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') || (*ptr >= '0' && *ptr <= '9') || (*ptr == '_')) {\n buffer[index++] = *ptr++;\n }\n buffer[index] = '\\0';\n\n if (is_keyword(buffer)) {\n printf(FG_BLUE \"%s\" RESET, buffer);\n } else {\n printf(\"%s\", buffer);\n }\n index = 0;\n } else if (*ptr >= '0' && *ptr <= '9') {\n while (*ptr >= '0' && *ptr <= '9') {\n buffer[index++] = *ptr++;\n }\n buffer[index] = '\\0';\n printf(FG_CYAN \"%s\" RESET, buffer);\n index = 0;\n } else {\n putchar(*ptr);\n ptr++;\n }\n }\n}\n\nvoid parse_markdown_to_ansi(const char *markdown) {\n const char *ptr = markdown;\n bool inside_code = false;\n\n while (*ptr) {\n if (*ptr == '`') {\n inside_code = !inside_code;\n if (inside_code) {\n printf(FG_YELLOW);\n } else {\n printf(RESET);\n }\n ptr++;\n continue;\n }\n\n if (inside_code) {\n char code_buffer[256];\n size_t index = 0;\n\n while (*ptr && *ptr != '`') {\n code_buffer[index++] = *ptr++;\n }\n code_buffer[index] = '\\0';\n highlight_code(code_buffer);\n } else {\n if (strncmp(ptr, \"**\", 2) == 0) {\n printf(BOLD);\n ptr += 2;\n while (*ptr && strncmp(ptr, \"**\", 2) != 0) putchar(*ptr++);\n if (*ptr == '*' && *(ptr + 1) == '*') ptr += 2;\n printf(RESET);\n }\n else if (*ptr == '*' && (ptr == markdown || *(ptr - 1) != '*')) {\n printf(ITALIC);\n ptr++;\n while (*ptr && *ptr != '*') putchar(*ptr++);\n if (*ptr == '*') ptr++;\n printf(RESET);\n }\n else if (strncmp(ptr, \"### \", 4) == 0) {\n printf(BOLD FG_YELLOW);\n ptr += 4;\n while (*ptr && *ptr != '\\n') putchar(*ptr++);\n printf(RESET \"\\n\");\n } else if (strncmp(ptr, \"## \", 3) == 0) {\n printf(BOLD FG_YELLOW);\n ptr += 3;\n while (*ptr && *ptr != '\\n') putchar(*ptr++);\n printf(RESET \"\\n\");\n } else if (strncmp(ptr, \"# \", 2) == 0) {\n printf(BOLD FG_YELLOW);\n ptr += 2;\n while (*ptr && *ptr != '\\n') putchar(*ptr++);\n printf(RESET \"\\n\");\n } else {\n putchar(*ptr);\n ptr++;\n }\n }\n }\n}",
"review": "**7**\n\n### Bugs\n- Potential buffer overflow in `highlight_code` and `parse_markdown_to_ansi` functions.\n- Use of hard-coded buffer size which may not be enough for large input.\n\n### Optimizations\n- Use dynamic strings or vector-like data structures to handle larger inputs safely.\n- Optimize the `is_keyword` function by using a hash set or another efficient data structure for keyword lookup.\n- Refactor common code patterns (like the `while` loops for parsing) into reusable helper functions to reduce redundancy.\n \n### Good Points\n- Clear use of ANSI escape codes for formatting which enhances code readability.\n- Proper division between handling code syntax and markdown syntax.\n- Inclusion of both code highlighting and markdown parsing in a single, cohesive codebase.\n- Follows good practices regarding licensing with the inclusion of the MIT License.\n\n### Summary\nThe code efficiently uses ANSI escape codes to highlight keywords in source code and parse markdown into ANSI-colored text. The main concerns are related to the safety of buffer usage, as it is prone to overflow when handling long inputs. The keyword detection could be optimized for speed, and the code could be made more reusable with refactoring. Overall, the program serves its purpose well but would benefit from improvements in robustness and efficiency.\n\n### Open source alternatives\n- **Pygments**: A generic syntax highlighter that supports many languages and formats.\n- **highlight.js**: A JavaScript library with similar functionality that works in browsers.\n- **Rouge**: A Ruby-based syntax highlighter compatible with over 100 languages.",
"filename": "markdown.h",
"path": "markdown.h",
"directory": "",
"grade": 7,
"size": 4933,
"line_count": 140
}