# HG changeset patch # User June Park # Date 1766531926 28800 # Node ID a30944e5719ea78807adfde8f4b9b8495b75cd0c # Parent fff1b048dda69852969bdd4567a58931924e032b Added vibe coded markdown to html script since it is useful for me. Updated Dowa so that it can be compiled without dirnet for windows. diff -r fff1b048dda6 -r a30944e5719e dowa/BUILD --- a/dowa/BUILD Tue Dec 23 14:00:37 2025 -0800 +++ b/dowa/BUILD Tue Dec 23 15:18:46 2025 -0800 @@ -1,6 +1,19 @@ load("@rules_cc//cc:cc_library.bzl", "cc_library") load("@rules_cc//cc:cc_test.bzl", "cc_test") +# TODO: Fix so that we can just define in the header instead of defining in the cc_library because this is ass. +cc_library( + name = "dowa_generic", + srcs = [ + "d_string.c", + "d_memory.c", + ], + hdrs = [ + "dowa.h", + "dowa_internal.h" + ], + visibility = ["//visibility:public"], +) cc_library( name = "dowa", @@ -12,6 +25,7 @@ "dowa.h", "dowa_internal.h" ], + copts = ["-DDIRECTORY"], visibility = ["//visibility:public"], ) diff -r fff1b048dda6 -r a30944e5719e dowa/d_memory.c --- a/dowa/d_memory.c Tue Dec 23 14:00:37 2025 -0800 +++ b/dowa/d_memory.c Tue Dec 23 15:18:46 2025 -0800 @@ -474,6 +474,7 @@ printf("-----------\n"); } +#ifdef DIRECTORY int Dowa_HashMap_Cache_Folder(Dowa_PHashMap p_hash_map, const char *folder_path) { if (!p_hash_map || !folder_path) @@ -503,12 +504,12 @@ FILE *f = fopen(fullpath, "rb"); if (!f) { perror("fopen"); continue; } + // Allocate exact file size (no extra byte for null terminator) void *buf = p_hash_map->p_arena ? - Dowa_Arena_Allocate(p_hash_map->p_arena, size + 1) : - malloc(size + 1); + Dowa_Arena_Allocate(p_hash_map->p_arena, size) : + malloc(size); if (!buf) { perror("malloc"); fclose(f); closedir(dir); return -1; } - if (fread(buf, 1, size, f) != size) { perror("fread"); @@ -518,8 +519,8 @@ } fclose(f); - ((char *)buf)[size] = '\0'; - Dowa_HashMap_Push_Value_With_Type(p_hash_map, entry->d_name, buf, size + 1, DOWA_HASH_MAP_TYPE_STRING); + // Store file data as-is without null terminator (for binary files like images) + Dowa_HashMap_Push_Value_With_Type(p_hash_map, entry->d_name, buf, size, DOWA_HASH_MAP_TYPE_STRING); if (!p_hash_map->p_arena) Dowa_Free(buf); // Dowa_HashMap_PushValue made its own copy } @@ -550,3 +551,4 @@ closedir(dir); return 0; } +#endif diff -r fff1b048dda6 -r a30944e5719e dowa/dowa.h --- a/dowa/dowa.h Tue Dec 23 14:00:37 2025 -0800 +++ b/dowa/dowa.h Tue Dec 23 15:18:46 2025 -0800 @@ -11,6 +11,7 @@ // Maybe move this into seobeo file directly? #include // some functions loop through files #endif + #include // I am not re-writing stuff I guess... #include @@ -119,8 +120,10 @@ // --- Utility Functions --- // /* Prints all entries in the hashmap to stdout for debugging purposes. */ extern void Dowa_HashMap_Print(Dowa_PHashMap map); +#ifdef DIRECTORY /* Loads all files from the specified folder into the hashmap. Uses file names as keys and file contents as values. Returns 0 on success, or -1 on failure. */ extern int Dowa_HashMap_Cache_Folder(Dowa_PHashMap map, const char *folder_path); +#endif #endif diff -r fff1b048dda6 -r a30944e5719e dowa/dowa_test.c --- a/dowa/dowa_test.c Tue Dec 23 14:00:37 2025 -0800 +++ b/dowa/dowa_test.c Tue Dec 23 15:18:46 2025 -0800 @@ -2,6 +2,7 @@ #include #include #include +#define DIRECTORY #include "dowa.h" int main(void) diff -r fff1b048dda6 -r a30944e5719e gui_ze/gui_ze.bzl --- a/gui_ze/gui_ze.bzl Tue Dec 23 14:00:37 2025 -0800 +++ b/gui_ze/gui_ze.bzl Tue Dec 23 15:18:46 2025 -0800 @@ -143,13 +143,17 @@ def _move_files_into_dir_impl(ctx): srcs = ctx.files.srcs + outs = [] for src in srcs: out = ctx.actions.declare_file(ctx.attr.dest + "/" + src.basename) - ctx.actions.symlink( - output = out, - target_file = src, + ctx.actions.run_shell( + inputs = [src], + outputs = [out], + command = "cp \"$1\" \"$2\"", + arguments = [src.path, out.path], ) - return [DefaultInfo(files = depset([out]))] + outs.append(out) + return [DefaultInfo(files = depset(outs))] move_files_into_dir = rule( implementation = _move_files_into_dir_impl, diff -r fff1b048dda6 -r a30944e5719e markdown_converter/BUILD --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/markdown_converter/BUILD Tue Dec 23 15:18:46 2025 -0800 @@ -0,0 +1,9 @@ +filegroup( + name = "markdown_to_html", + srcs = glob([ + "**/*.js", + ], allow_empty=True), + visibility = ["//visibility:public"], +) + + diff -r fff1b048dda6 -r a30944e5719e markdown_converter/main.js --- a/markdown_converter/main.js Tue Dec 23 14:00:37 2025 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -// # -// ## -// []() -// _ _ -// * * -// 1. -// - -// \s\s -// - -function Lexer(character) { -} - -/** - * @params - * value: string - */ -function mardownConverter(value) { - let i = 0; - let character; - const domElements = []; - while (i < value.length) { - character = value[i] - switch(character) { - case "#": { - if - const dom = document.createElement("h1"); - domElements.append(dom) - } - case "_": { - } - case "_" { - } - case "*" { - } - default { - return character; - } - } - } -} diff -r fff1b048dda6 -r a30944e5719e markdown_converter/markdown_to_html.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/markdown_converter/markdown_to_html.js Tue Dec 23 15:18:46 2025 -0800 @@ -0,0 +1,269 @@ +/** + * Simple Markdown to HTML Converter + * Supports: headers, bold, italic, links, lists, code blocks, line breaks + */ + +/** + * Create heading element (H1-H6) + * @param {string} text - The heading text + * @param {number} level - Heading level (1-6) + * @returns {HTMLElement} + */ +function createHeadingElement(text, level) { + const h = document.createElement(`H${level}`); + const t = document.createTextNode(text.trim()); + h.appendChild(t); + return h; +} + +/** + * Create paragraph element + * @param {string} text - The paragraph text + * @returns {HTMLElement} + */ +function createParagraphElement(text) { + const p = document.createElement("P"); + p.innerHTML = processInlineMarkdown(text.trim()); + return p; +} + +/** + * Create link element + * @param {string} text - Link text + * @param {string} url - Link URL + * @returns {HTMLElement} + */ +function createLinkElement(text, url) { + const a = document.createElement("A"); + a.href = url; + a.textContent = text; + return a; +} + +/** + * Create unordered list element + * @param {Array} items - List items + * @returns {HTMLElement} + */ +function createUnorderedList(items) { + const ul = document.createElement("UL"); + items.forEach(item => { + const li = document.createElement("LI"); + li.innerHTML = processInlineMarkdown(item.trim()); + ul.appendChild(li); + }); + return ul; +} + +/** + * Create ordered list element + * @param {Array} items - List items + * @returns {HTMLElement} + */ +function createOrderedList(items) { + const ol = document.createElement("OL"); + items.forEach(item => { + const li = document.createElement("LI"); + li.innerHTML = processInlineMarkdown(item.trim()); + ol.appendChild(li); + }); + return ol; +} + +/** + * Create code block element + * @param {string} code - Code content + * @returns {HTMLElement} + */ +function createCodeBlock(code) { + const pre = document.createElement("PRE"); + const codeEl = document.createElement("CODE"); + codeEl.textContent = code; + pre.appendChild(codeEl); + return pre; +} + +/** + * Create blockquote element + * @param {string} text - Quote text + * @returns {HTMLElement} + */ +function createBlockquote(text) { + const blockquote = document.createElement("BLOCKQUOTE"); + blockquote.innerHTML = processInlineMarkdown(text.trim()); + return blockquote; +} + +/** + * Create horizontal rule + * @returns {HTMLElement} + */ +function createHorizontalRule() { + return document.createElement("HR"); +} + +/** + * Process inline markdown (bold, italic, code, links) + * @param {string} text - Text with inline markdown + * @returns {string} HTML string + */ +function processInlineMarkdown(text) { + // Links: [text](url) + text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); + + // Images: ![alt](url) + text = text.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '$1'); + + // Bold: **text** or __text__ + text = text.replace(/\*\*([^*]+)\*\*/g, '$1'); + text = text.replace(/__([^_]+)__/g, '$1'); + + // Italic: *text* or _text_ + text = text.replace(/\*([^*]+)\*/g, '$1'); + text = text.replace(/_([^_]+)_/g, '$1'); + + // Inline code: `code` + const x = /`([^`]+)`/g; + text = text.replace(x, '$1'); + + // Strikethrough: ~~text~~ + text = text.replace(/~~([^~]+)~~/g, '$1'); + + // Line breaks: two spaces at end of line + text = text.replace(/ \n/g, '
\n'); + + return text; +} + +/** + * Main markdown converter function + * @param {string} value - Markdown string + * @returns {Array} Array of DOM elements + */ +function markdownConverter(value) { + const lines = value.split('\n'); + const domElements = []; + let i = 0; + + while (i < lines.length) { + const line = lines[i]; + const trimmedLine = line.trim(); + + // Skip empty lines + if (trimmedLine === '') { + i++; + continue; + } + + if (trimmedLine.startsWith('#')) + { + const match = trimmedLine.match(/^(#{1,6})\s+(.+)$/); + if (match) { + const level = match[1].length; + const text = match[2]; + domElements.push(createHeadingElement(text, level)); + i++; + continue; + } + } + + if (trimmedLine.startsWith('```')) { + let codeContent = ''; + i++; // Skip opening ``` + while (i < lines.length && !lines[i].trim().startsWith('```')) { + codeContent += lines[i] + '\n'; + i++; + } + domElements.push(createCodeBlock(codeContent)); + i++; // Skip closing ``` + continue; + } + + // Blockquote: > + if (trimmedLine.startsWith('>')) { + let quoteContent = ''; + while (i < lines.length && lines[i].trim().startsWith('>')) { + quoteContent += lines[i].trim().substring(1).trim() + ' '; + i++; + } + domElements.push(createBlockquote(quoteContent)); + continue; + } + + // Horizontal rule: ---, ***, ___ + if (trimmedLine.match(/^(-{3,}|\*{3,}|_{3,})$/)) { + domElements.push(createHorizontalRule()); + i++; + continue; + } + + // Unordered list: -, *, + + if (trimmedLine.match(/^[-*+]\s+/)) { + const listItems = []; + while (i < lines.length && lines[i].trim().match(/^[-*+]\s+/)) { + listItems.push(lines[i].trim().substring(2)); + i++; + } + domElements.push(createUnorderedList(listItems)); + continue; + } + + // Ordered list: 1., 2., etc. + if (trimmedLine.match(/^\d+\.\s+/)) { + const listItems = []; + while (i < lines.length && lines[i].trim().match(/^\d+\.\s+/)) { + listItems.push(lines[i].trim().replace(/^\d+\.\s+/, '')); + i++; + } + domElements.push(createOrderedList(listItems)); + continue; + } + + // Regular paragraph + let paragraphContent = ''; + while (i < lines.length && lines[i].trim() !== '' && + !lines[i].trim().match(/^(#{1,6}\s|[-*+]\s|\d+\.\s|>|```|---|\*\*\*|___)/)) { + paragraphContent += lines[i] + ' '; + i++; + } + if (paragraphContent.trim()) { + domElements.push(createParagraphElement(paragraphContent)); + } + } + + return domElements; +} + +/** + * Helper function to append all elements to a container + * @param {HTMLElement} container - Container element + * @param {string} markdown - Markdown string + */ +function renderMarkdown(container, markdown) { + const elements = markdownConverter(markdown); + elements.forEach(el => container.appendChild(el)); +} + +// Example usage: +// const markdown = ` +// # Heading 1 +// ## Heading 2 +// +// This is a paragraph with **bold** and *italic* text. +// +// - List item 1 +// - List item 2 +// +// 1. Ordered item 1 +// 2. Ordered item 2 +// +// [Link text](https://example.com) +// `; +// +// const container = document.getElementById('content'); +// renderMarkdown(container, markdown); + +// Export for use in other files +if (typeof module !== 'undefined' && module.exports) { + module.exports = { markdownConverter, renderMarkdown }; +} diff -r fff1b048dda6 -r a30944e5719e mrjunejune/BUILD --- a/mrjunejune/BUILD Tue Dec 23 14:00:37 2025 -0800 +++ b/mrjunejune/BUILD Tue Dec 23 15:18:46 2025 -0800 @@ -7,6 +7,7 @@ name = "compiled_ts", srcs = [ "//playground:hello", + "//markdown_converter:markdown_to_html" ], dest = "pages", ) diff -r fff1b048dda6 -r a30944e5719e mrjunejune/pages/markdown_to_html/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrjunejune/pages/markdown_to_html/index.html Tue Dec 23 15:18:46 2025 -0800 @@ -0,0 +1,257 @@ + + + + + + Markdown to HTML Converter + + + +
+

Markdown to HTML Converter

+
+ +
+
+
Markdown Input
+ +
+ +
+
HTML Output
+
+
+
+ + + + + diff -r fff1b048dda6 -r a30944e5719e seobeo/seobeo.h --- a/seobeo/seobeo.h Tue Dec 23 14:00:37 2025 -0800 +++ b/seobeo/seobeo.h Tue Dec 23 15:18:46 2025 -0800 @@ -8,6 +8,11 @@ * Library for starting TCP, UDP server and serving static file or path. */ +// Define DIRECTORY before any includes to enable directory operations in dowa.h +#ifndef DIRECTORY +#define DIRECTORY +#endif + #include #include #include diff -r fff1b048dda6 -r a30944e5719e seobeo/seobeo_internal.h --- a/seobeo/seobeo_internal.h Tue Dec 23 14:00:37 2025 -0800 +++ b/seobeo/seobeo_internal.h Tue Dec 23 15:18:46 2025 -0800 @@ -5,6 +5,9 @@ #include #include +#ifndef DIRECTORY +#define DIRECTORY +#endif #include "dowa/dowa.h" typedef enum {