add creation of default page
authorLukas Hägele <lukas.haegele93@web.de>
Sun, 6 Oct 2024 14:17:30 +0000 (16:17 +0200)
committerLukas Hägele <lukas.haegele93@web.de>
Sun, 6 Oct 2024 14:17:30 +0000 (16:17 +0200)
src/html.c

index 801f0f4a8b99589a7681d8c8caa6889ed278d896..5fbe59bc9173b33491dee0732368307326cbe1ad 100644 (file)
@@ -10,6 +10,7 @@
 
 #define ElementNameTable \
     X(invalid) \
+    X(root)    \
                \
     X(html)    \
     X(head)    \
@@ -17,6 +18,9 @@
     X(title)   \
     X(style)   \
     X(body)    \
+    X(header)  \
+    X(main)    \
+    X(article) \
                \
     X(h1)      \
     X(h2)      \
@@ -42,14 +46,14 @@ typedef struct html_attribute
     struct html_attribute* Next;
 
     str Key;
-    str Value;
+    str Child;
 } html_attribute;
 
 typedef struct html_element
 {
     struct html_element* Prev;
     struct html_element* Next;
-    struct html_element* Value;
+    struct html_element* Child;
 
     u8 ElementName;
     union {
@@ -58,13 +62,9 @@ typedef struct html_element
     };
 } html_element;
 
+/* todo: remove? */
 typedef html_element html;
 
-typedef struct
-{
-    html_element Html;
-} html_markdownContext;
-
 static void
 appendElement(html_element* Sentinel, html_element* Element)
 {
@@ -74,11 +74,136 @@ appendElement(html_element* Sentinel, html_element* Element)
     Element->Next = Sentinel;
 }
 
+static html_element*
+createElement(html_element_name Name, arena* Arena)
+{
+    html_element* Element = ARENA_PUSH_STRUCT(Arena, html_element);
+
+    Element->Next = Element;
+    Element->Prev = Element;
+
+    Element->ElementName = Name;
+
+    html_element* Child = ARENA_PUSH_STRUCT(Arena, html_element);
+    {
+        Child->Next = Child;
+        Child->Prev = Child;
+    }
+    Element->Child = Child;
+
+    return Element;
+}
+
+static inline void
+addAttribute(html_element* Element, str Key, str Child, arena* Arena)
+{
+    html_attribute* Attribute = ARENA_PUSH_STRUCT(Arena, html_attribute);
+    {
+        Attribute->Key   = Key;
+        Attribute->Child = Child;
+    }
+
+    Element->Attribute = Attribute;
+}
+
+static inline void
+appendValue(html_element* Target, html_element* Child)
+{
+    ASSERT(!"not yet implemented");
+}
+
+static inline void
+addContent(html_element* Target, str ContentStr, arena* Arena)
+{
+    html_element* Content = ARENA_PUSH_STRUCT(Arena, html_element);
+    {
+        Content->ElementName = HTML_ELEMENT_NAME_content;
+        Content->Content     = ContentStr;
+    }
+
+    Target->Child = Content;
+}
+
+static html*
+html_createDefault(arena* Arena)
+{
+    html* Root = createElement(HTML_ELEMENT_NAME_root, Arena);
+    {
+        html_element* Doctype = createElement(HTML_ELEMENT_NAME_content, Arena);
+        {
+            addContent(Doctype, STR_LITERAL("<!DOCTYPE html>"), Arena);
+            appendValue(Root, Doctype);
+        }
+
+        html_element* Html = createElement(HTML_ELEMENT_NAME_html, Arena);
+        {
+            addAttribute(Root, STR_LITERAL("lang"), STR_LITERAL("'de-DE'"), Arena);
+            appendValue(Root, Html);
+        }
+
+        html_element* Head = createElement(HTML_ELEMENT_NAME_head, Arena);
+        {
+            appendValue(Root, Head);
+
+            html_element* MetaCharset = createElement(HTML_ELEMENT_NAME_meta, Arena);
+            {
+                addAttribute(MetaCharset, STR_LITERAL("charset"), STR_LITERAL("'utf-8'"), Arena);
+                appendValue(Head, MetaCharset);
+            }
+
+            html_element* MetaViewport = createElement(HTML_ELEMENT_NAME_meta, Arena);
+            {
+                addAttribute(MetaViewport, STR_LITERAL("name"), STR_LITERAL("'viewport'"), Arena);
+                addAttribute(MetaViewport, STR_LITERAL("content"), STR_LITERAL("'width=device-width, initial-scale=1'"), Arena);
+                appendValue(Head, MetaViewport);
+            }
+
+            /* todo: add later? */
+            html_element* Title = createElement(HTML_ELEMENT_NAME_title, Arena);
+            {
+                addContent(Title, STR_LITERAL("<untitled>"), Arena);
+                appendValue(Head, Title);
+            }
+
+            /* todo: add style? */
+        }
+
+        html_element* Body = createElement(HTML_ELEMENT_NAME_body, Arena);
+        {
+            appendValue(Root, Body);
+
+            html_element* Header = createElement(HTML_ELEMENT_NAME_header, Arena);
+            {
+                appendValue(Body, Header);
+
+                html_element* Heading = createElement(HTML_ELEMENT_NAME_h1, Arena);
+                {
+                    addContent(Heading, STR_LITERAL("Meine Rezeptsammlung"), Arena);
+                    appendValue(Header, Heading);
+                }
+            }
+
+            html_element* Main = createElement(HTML_ELEMENT_NAME_main, Arena);
+            {
+                appendValue(Body, Main);
+
+                html_element* Article = createElement(HTML_ELEMENT_NAME_article, Arena);
+                {
+                    appendValue(Main, Article);
+                }
+            }
+        }
+    }
+
+    return Root;
+}
+
 static inline html_element*
 createContent(str ContentStr, arena* Arena)
 {
     ContentStr = str_stripHead(ContentStr);
 
+    /* todo: use addContent() */
     html_element* Content = ARENA_PUSH_STRUCT(Arena, html_element);
     {
         Content->ElementName = HTML_ELEMENT_NAME_content;
@@ -122,7 +247,7 @@ parseHeading(str Line, html_element* Html, arena* Arena)
             HeadingContent.Capacity -= Depth;
         }
 
-        Heading->Value = createContent(HeadingContent, Arena);
+        Heading->Child = createContent(HeadingContent, Arena);
     }
 
     /* todo: check if this is actually the sentinel! */
@@ -147,7 +272,7 @@ parseListItem(str Line, html_element* Html, arena* Arena)
             ListItemContent.Capacity -= 1u;
         }
 
-        ListItem->Value = createContent(ListItemContent, Arena);
+        ListItem->Child = createContent(ListItemContent, Arena);
     }
 
     /* append to unordered list */
@@ -165,7 +290,7 @@ parseListItem(str Line, html_element* Html, arena* Arena)
             List->ElementName = HTML_ELEMENT_NAME_ul;
         }
 
-        html_element* ListItemSentinel = List->Value;
+        html_element* ListItemSentinel = List->Child;
         appendElement(ListItemSentinel, ListItem);
     }
 }
@@ -173,10 +298,11 @@ parseListItem(str Line, html_element* Html, arena* Arena)
 static void
 parseParagraph(str Line, html_element* Html, arena* Arena)
 {
+    /* todo: use addContent? */
     html_element* ParagraphItem = ARENA_PUSH_STRUCT(Arena, html_element);
     {
         ParagraphItem->ElementName = HTML_ELEMENT_NAME_content;
-        ParagraphItem->Value       = createContent(Line, Arena);
+        ParagraphItem->Child       = createContent(Line, Arena);
     }
 
     /* append to paragraph */
@@ -195,7 +321,7 @@ parseParagraph(str Line, html_element* Html, arena* Arena)
             Paragraph = PrevElement;
         }
 
-        html_element* ParagraphSentinel = Paragraph->Value;
+        html_element* ParagraphSentinel = Paragraph->Child;
         appendElement(ParagraphSentinel, ParagraphItem);
     }
 }
@@ -228,7 +354,7 @@ parseLine(str Line, html_element* Html, arena* Arena)
 static html
 html_parseMarkdown(str Source, arena* Arena)
 {
-    html_element Html = html_create();
+    html_element Html = html_create(Arena);
 
     for (str Line = str_getLine(Source);
          str_isValid(Line);
@@ -296,13 +422,13 @@ serializeElement(str* Sentinel, html_element* Element)
                 {
                     str_append(Sentinel, Attribute->Key);
                     str_append(Sentinel, STR_LITERAL("=\""));
-                    str_append(Sentinel, Attribute->Value);
+                    str_append(Sentinel, Attribute->Child);
                     str_append(Sentinel, STR_LITERAL("\""));
                 }
             }
             str_append(Sentinel, STR_LITERAL(">"));
 
-            serializeElement(Sentinel, Element->Value);
+            serializeElement(Sentinel, Element->Child);
 
             str_append(Sentinel, STR_LITERAL("<"));
             str_append(Sentinel, STR_LITERAL(ElementNames[Element->ElementName]));