comparison markdown_converter/markdown_to_html.c @ 184:8c74204fd362

[MD to HTML] Updated so it can be used through readme to html
author MrJuneJune <me@mrjunejune.com>
date Fri, 23 Jan 2026 22:20:35 -0800
parents 1c0878eb17de
children a2725419f988
comparison
equal deleted inserted replaced
183:a8976a008a9d 184:8c74204fd362
1 #include <string.h> 1 #include <string.h>
2 #include <stdlib.h> 2 #include <stdlib.h>
3 #include <stdio.h> 3 #include <stdio.h>
4 #include <ctype.h> 4 #include <ctype.h>
5 #include "markdown_converter/markdown_to_html.h" 5 #include "markdown_converter/markdown_to_html.h"
6
7 // JavaScript needs this to free the memory later
8 MDAPI void *wasm_alloc(size_t size) {
9 return malloc(size);
10 }
11
12 MDAPI void wasm_free(void* ptr) {
13 free(ptr);
14 }
6 15
7 #define INITIAL_BUFFER_SIZE 1024 * 1024 // 1MB 16 #define INITIAL_BUFFER_SIZE 1024 * 1024 // 1MB
8 17
9 // String buffer for building HTML output 18 // String buffer for building HTML output
10 typedef struct { 19 typedef struct {
128 // Check if line is unordered list item 137 // Check if line is unordered list item
129 static int is_unordered_list(const char *line) 138 static int is_unordered_list(const char *line)
130 { 139 {
131 line = skip_whitespace(line); 140 line = skip_whitespace(line);
132 return (*line == '-' || *line == '*' || *line == '+') && line[1] == ' '; 141 return (*line == '-' || *line == '*' || *line == '+') && line[1] == ' ';
142 }
143
144 // Check if line starts with an HTML tag
145 static int is_html_block_start(const char *line)
146 {
147 line = skip_whitespace(line);
148 if (*line != '<') return 0;
149 line++;
150
151 // Check for closing tag or comment
152 if (*line == '/' || *line == '!') return 1;
153
154 // Check for valid tag name (letter followed by alphanumeric)
155 if (!isalpha((unsigned char)*line)) return 0;
156
157 return 1;
158 }
159
160 // Check if line starts with a specific HTML tag (e.g., "script", "style")
161 static int is_html_tag(const char *line, const char *tag)
162 {
163 line = skip_whitespace(line);
164 if (*line != '<') return 0;
165 line++;
166
167 // Skip optional /
168 int is_closing = 0;
169 if (*line == '/') {
170 is_closing = 1;
171 line++;
172 }
173
174 size_t tag_len = strlen(tag);
175 if (strncasecmp(line, tag, tag_len) != 0) return 0;
176
177 char next = line[tag_len];
178 // Tag must be followed by space, >, or end for closing tags
179 return next == '>' || next == ' ' || next == '\t' || next == '\n' || next == '\0';
133 } 180 }
134 181
135 // Check if line is ordered list item 182 // Check if line is ordered list item
136 static int is_ordered_list(const char *line) 183 static int is_ordered_list(const char *line)
137 { 184 {
483 530
484 buffer_append(buf, "</ol>"); 531 buffer_append(buf, "</ol>");
485 continue; 532 continue;
486 } 533 }
487 534
535 // HTML block - pass through unchanged
536 if (is_html_block_start(line)) {
537 // Check if it's a script or style tag that needs special handling
538 int is_script = is_html_tag(line, "script");
539 int is_style = is_html_tag(line, "style");
540
541 if (is_script || is_style) {
542 const char *end_tag = is_script ? "</script>" : "</style>";
543
544 // Output the opening line
545 buffer_append(buf, line);
546 buffer_append_char(buf, '\n');
547
548 free(line);
549 if (*ptr == '\n') ptr++;
550
551 // Collect content until closing tag
552 while (*ptr) {
553 line_start = ptr;
554 while (*ptr && *ptr != '\n') ptr++;
555 line_len = ptr - line_start;
556
557 line = (char *)malloc(line_len + 1);
558 if (!line) break;
559 memcpy(line, line_start, line_len);
560 line[line_len] = '\0';
561
562 buffer_append(buf, line);
563 buffer_append_char(buf, '\n');
564
565 int found_end = (strstr(line, end_tag) != NULL);
566 free(line);
567 if (*ptr == '\n') ptr++;
568
569 if (found_end) break;
570 }
571 continue;
572 }
573
574 // Regular HTML tag - just pass through the line
575 buffer_append(buf, line);
576 buffer_append_char(buf, '\n');
577 free(line);
578 if (*ptr == '\n') ptr++;
579 continue;
580 }
581
488 // Regular paragraph 582 // Regular paragraph
489 buffer_append(buf, "<p>"); 583 buffer_append(buf, "<p>");
490 584
491 while (1) { 585 while (1) {
492 const char *content = skip_whitespace(line); 586 const char *content = skip_whitespace(line);
510 count_heading_level(line) > 0 || 604 count_heading_level(line) > 0 ||
511 starts_with(line, "```") || 605 starts_with(line, "```") ||
512 starts_with(line, ">") || 606 starts_with(line, ">") ||
513 is_horizontal_rule(line) || 607 is_horizontal_rule(line) ||
514 is_unordered_list(line) || 608 is_unordered_list(line) ||
515 is_ordered_list(line)) { 609 is_ordered_list(line) ||
610 is_html_block_start(line)) {
516 ptr = line_start; 611 ptr = line_start;
517 free(line); 612 free(line);
518 break; 613 break;
519 } 614 }
520 615