Mercurial
changeset 78:e7bf9e002850
amend
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 31 Dec 2025 15:07:43 -0800 |
| parents | c348ac875294 |
| children | 5710108c949e |
| files | mrjunejune/main.c mrjunejune/pages/index.html mrjunejune/pages/parts/header.html mrjunejune/pages/parts/headers.html mrjunejune/pages/resume/index.html mrjunejune/pages/tools/index.html mrjunejune/pages/tools/markdown_to_html/index.html seobeo/s_router.c seobeo/s_web.c seobeo/seobeo.h |
| diffstat | 10 files changed, 195 insertions(+), 124 deletions(-) [+] |
line wrap: on
line diff
--- a/mrjunejune/main.c Wed Dec 31 14:17:40 2025 -0800 +++ b/mrjunejune/main.c Wed Dec 31 15:07:43 2025 -0800 @@ -8,20 +8,88 @@ stop_server = 1; } +void Seobeo_ServerSideRender( + char *final_body, + char *path, + Dowa_Arena *arena +) { + size_t html_size = 0; + char *template = Seobeo_Web_LoadFile(path, &html_size); + if (!template) return; + + size_t current_offset = 0; + char *cursor = template; + + int32 token_len = 2; + + while (true) + { + char *start_tag = strstr(cursor, "{{"); + if (!start_tag) break; + + char *end_tag = strstr(start_tag, "}}"); + if (!end_tag) break; + + size_t leading_len = start_tag - cursor; + memcpy(final_body + current_offset, cursor, leading_len); + current_offset += leading_len; + + size_t name_len = end_tag - (start_tag + token_len); + char *include_name = Dowa_Arena_Allocate(arena, name_len + 1); + memcpy(include_name, start_tag + token_len, name_len); + include_name[name_len] = '\0'; + + size_t sub_file_size = 0; + char *sub_content = Seobeo_Web_LoadFile(include_name, &sub_file_size); + if (sub_content) + { + memcpy(final_body + current_offset, sub_content, sub_file_size); + current_offset += sub_file_size; + free(sub_content); + } + + cursor = end_tag + 2; + } + strcpy(final_body + current_offset, cursor); + free(template); +} + Seobeo_Request_Entry* GetHomePage(Seobeo_Request_Entry *req, Dowa_Arena *arena) { - Seobeo_Request_Entry *resp = NULL; - char *body = Dowa_Arena_Allocate(arena, 10 * 1024); - size_t body_size = 0; - char *file_content = Seobeo_Web_LoadFile("/index.html", &body_size); - snprintf(body, 10 * 1024, file_content); - free(file_content); + Seobeo_Request_Entry *resp = NULL; + char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); // 50KB buffer + Seobeo_ServerSideRender(final_body, "/index.html", arena); + Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); + return resp; +} - Dowa_HashMap_Push_Arena(resp, "body", body, arena); +Seobeo_Request_Entry* GetResume(Seobeo_Request_Entry *req, Dowa_Arena *arena) +{ + Seobeo_Request_Entry *resp = NULL; + char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); + Seobeo_ServerSideRender(final_body, "/resume/index.html", arena); + Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); + return resp; +} + +Seobeo_Request_Entry* GetTools(Seobeo_Request_Entry *req, Dowa_Arena *arena) +{ + Seobeo_Request_Entry *resp = NULL; + char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); + Seobeo_ServerSideRender(final_body, "/tools/index.html", arena); + Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); return resp; } +Seobeo_Request_Entry* GetMDToHTML(Seobeo_Request_Entry *req, Dowa_Arena *arena) +{ + Seobeo_Request_Entry *resp = NULL; + char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); + Seobeo_ServerSideRender(final_body, "/tools/markdown_to_html/index.html", arena); + Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); + return resp; +} Seobeo_Request_Entry* GetUser(Seobeo_Request_Entry *req, Dowa_Arena *arena) { @@ -36,10 +104,20 @@ return resp; } - int main(void) { Seobeo_Router_Init(); Seobeo_Router_Register("GET", "/", GetHomePage); + Seobeo_Router_Register("GET", "/index.html", GetHomePage); + + Seobeo_Router_Register("GET", "/resume", GetResume); + Seobeo_Router_Register("GET", "/resume/index.html", GetResume); + + Seobeo_Router_Register("GET", "/tools", GetTools); + Seobeo_Router_Register("GET", "/tools/index.html", GetTools); + + Seobeo_Router_Register("GET", "/tools/markdown_to_html", GetMDToHTML); + Seobeo_Router_Register("GET", "/tools/markdown_to_html/index.html", GetMDToHTML); + Seobeo_Web_Server_Start("mrjunejune/pages", "6969", SEOBEO_MODE_EDGE, 2); }
--- a/mrjunejune/pages/index.html Wed Dec 31 14:17:40 2025 -0800 +++ b/mrjunejune/pages/index.html Wed Dec 31 15:07:43 2025 -0800 @@ -6,7 +6,7 @@ </head> <body> <main> - <^ parts/header.html ^> + {{/parts/header.html}} <h1> Useful scripts </h1> <ul> <li> <a href="/resume"> Resume </a> </li>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrjunejune/pages/parts/header.html Wed Dec 31 15:07:43 2025 -0800 @@ -0,0 +1,102 @@ +<header> + <nav> + <h2 class="header-logo"> + <div id="themeToggle"> + <img id="epiChan" class="epi-logo" aria-label="Toggle dark mode" src="/public/epi_favicon.svg" height="50" width="50"> + </div> + <a href="/">MrJuneJune</a> + </h2> + <div class="internal-links"> + <a href="/resume">Resume</a> + <a href="/tools">Tools</a> + </div> + <div class="social-links"> + <a href="https://github.com/mrjunejune" target="_blank"> + <svg viewBox="0 0 16 16" aria-hidden="true" width="32" height="32" + ><path + fill="currentColor" + d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z" + ></path></svg> + </a> + </div> + </nav> +</header> +<style> + :root { + --header-background: var(--white); + --header-color: rgb(var(--black)); + --link-hover-accent: var(--awesome); + --social-link-hover: rgb(var(--gray-dark)); + } + .internal-links { + width: 33%; + } + .header-logo { + display: flex; + align-items: center; + } + header { + margin: auto; + padding: 0 1em; + background: var(--header-background); + color: rgb(var(--header-color)); + font-family: "Atkinson", sans-serif; + box-shadow: 0 2px 8px rgba(var(--black), 5%); + width: 720px; + max-width: calc(100% - 2em); + + } + h2 { + margin: 0; + font-size: 1em; + } + h2 a, + h2 a.active { + text-decoration: none; + } + nav { + display: flex; + align-items: center; + justify-content: space-between; + } + nav a { + padding: 1em 0.5em; + color: rgb(var(--header-color)); + border-bottom: 4px solid transparent; + text-decoration: none; + } + nav a.active { + text-decoration: none; + border-bottom-color: var(--link-hover-accent); + } + .social-links, + .social-links a { + display: flex; + } + .social-links a { + text-decoration: none; + } + .social-links a:hover { + color: rgb(var(--social-link-hover)); + } + @media (max-width: 720px) { + .social-links { + display: none; + } + .internal-links { + width: 45%; + } + } + :global(.dark) img { + -webkit-filter: invert(1); /* safari 6.0 - 9.0 */ + filter: invert(1); + } + #themeToggle { + background: var(--header-background); + display: flex; + align-items: center; + border-radius: 25px; + filter: invert(1); + cursor: pointer; + } +</style>
--- a/mrjunejune/pages/parts/headers.html Wed Dec 31 14:17:40 2025 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -<header> - <nav> - <h2 class="header-logo"> - <div id="themeToggle"> - <img id="epiChan" class="epi-logo" aria-label="Toggle dark mode" src="/public/epi_favicon.svg" height="50" width="50"> - </div> - <a href="/">MrJuneJune</a> - </h2> - <div class="internal-links"> - <a href="/resume">Resume</a> - <a href="/tools">Tools</a> - </div> - <div class="social-links"> - <a href="https://github.com/mrjunejune" target="_blank"> - <svg viewBox="0 0 16 16" aria-hidden="true" width="32" height="32" - ><path - fill="currentColor" - d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z" - ></path></svg> - </a> - </div> - </nav> -</header> -<style> - :root { - --header-background: var(--white); - --header-color: rgb(var(--black)); - --link-hover-accent: var(--awesome); - --social-link-hover: rgb(var(--gray-dark)); - } - .internal-links { - width: 33%; - } - .header-logo { - display: flex; - align-items: center; - } - header { - margin: auto; - padding: 0 1em; - background: var(--header-background); - color: rgb(var(--header-color)); - font-family: "Atkinson", sans-serif; - box-shadow: 0 2px 8px rgba(var(--black), 5%); - width: 720px; - max-width: calc(100% - 2em); - - } - h2 { - margin: 0; - font-size: 1em; - } - h2 a, - h2 a.active { - text-decoration: none; - } - nav { - display: flex; - align-items: center; - justify-content: space-between; - } - nav a { - padding: 1em 0.5em; - color: rgb(var(--header-color)); - border-bottom: 4px solid transparent; - text-decoration: none; - } - nav a.active { - text-decoration: none; - border-bottom-color: var(--link-hover-accent); - } - .social-links, - .social-links a { - display: flex; - } - .social-links a { - text-decoration: none; - } - .social-links a:hover { - color: rgb(var(--social-link-hover)); - } - @media (max-width: 720px) { - .social-links { - display: none; - } - .internal-links { - width: 45%; - } - } - :global(.dark) img { - -webkit-filter: invert(1); /* safari 6.0 - 9.0 */ - filter: invert(1); - } - #themeToggle { - background: var(--header-background); - display: flex; - align-items: center; - border-radius: 25px; - filter: invert(1); - cursor: pointer; - } -</style> -<script>
--- a/mrjunejune/pages/resume/index.html Wed Dec 31 14:17:40 2025 -0800 +++ b/mrjunejune/pages/resume/index.html Wed Dec 31 15:07:43 2025 -0800 @@ -1,12 +1,11 @@ <!doctype html> <html lang="en"> <head> - <BaseHead title="Resume" description="June's resume" /> <link rel="stylesheet" href="base.css" /> <link rel="stylesheet" href="resume.css" /> </head> <body> - <button class="dark-mode-toggle" aria-label="Toggle dark mode">🔄</button> + {{/parts/header.html}} <main> <div class="info"> <p><span class="header-firstname-style"> JUNTAE </span><span class="header-lastname-style">PARK</span><p>
--- a/mrjunejune/pages/tools/index.html Wed Dec 31 14:17:40 2025 -0800 +++ b/mrjunejune/pages/tools/index.html Wed Dec 31 15:07:43 2025 -0800 @@ -6,7 +6,7 @@ <link rel="stylesheet" href="/tools/index.css" /> </head> <body> - <div id="header"></div> + {{/parts/header.html}} <main> <h1 class="title"> Tools </h1> <ul class="nav-list"> @@ -14,5 +14,4 @@ </ul> </main> </body> - <script src="/index.js"></script> </html>
--- a/mrjunejune/pages/tools/markdown_to_html/index.html Wed Dec 31 14:17:40 2025 -0800 +++ b/mrjunejune/pages/tools/markdown_to_html/index.html Wed Dec 31 15:07:43 2025 -0800 @@ -8,7 +8,7 @@ <link rel="stylesheet" href="markdown_to_html/index.css" /> </head> <body> - <div id="header"></div> + {{/parts/header.html}} <div class="header"> <h1>Markdown to HTML Converter</h1> </div>
--- a/seobeo/s_router.c Wed Dec 31 14:17:40 2025 -0800 +++ b/seobeo/s_router.c Wed Dec 31 15:07:43 2025 -0800 @@ -18,7 +18,7 @@ void Seobeo_Router_Init() { - g_routes = NULL; + Dowa_Array_Reserve(g_routes, 20); } void Seobeo_Router_Register(const char *method, const char *path_pattern, Seobeo_Route_Handler handler) @@ -144,7 +144,7 @@ } // Default text plain - const char *content_type = "text/plain"; + const char *content_type = "text/html"; void *p_content_type_kv = Dowa_HashMap_Get_Ptr(p_response_map, "content-type"); if (p_content_type_kv) {
--- a/seobeo/s_web.c Wed Dec 31 14:17:40 2025 -0800 +++ b/seobeo/s_web.c Wed Dec 31 15:07:43 2025 -0800 @@ -138,13 +138,9 @@ // --- Try to match API route first --- Seobeo_Route_Handler handler = Seobeo_Router_Find_Handler(method, path, &p_req_map, p_request_arena); - if (handler != NULL) { - // Call the API handler Seobeo_Request_Entry *p_response_map = handler(p_req_map, p_response_arena); - - // Send the response Seobeo_Router_Send_Response(p_cli_handle, p_response_map, p_response_arena); goto clean_up; }
--- a/seobeo/seobeo.h Wed Dec 31 14:17:40 2025 -0800 +++ b/seobeo/seobeo.h Wed Dec 31 15:07:43 2025 -0800 @@ -74,7 +74,7 @@ extern Seobeo_Route_Handler Seobeo_Router_Find_Handler(const char *method, const char *path, Seobeo_Request_Entry **pp_request_map, Dowa_Arena *p_arena); /* Send HTTP response from response map (internal use) */ extern void Seobeo_Router_Send_Response(Seobeo_Handle *p_handle, Seobeo_Request_Entry *p_response_map, Dowa_Arena *p_arena); -extern char *Seobeo_Web_LoadFile(const char *file_path, size_t *p_file_size) +extern char *Seobeo_Web_LoadFile(const char *file_path, size_t *p_file_size); // --- Helper functions --- // /* Destroy handle. It will handle all NULL poointers. */