From 64c19f4f12fd532e3329fb312cf0467190e210c2 Mon Sep 17 00:00:00 2001
From: Allen Webster <editor@4coder.net>
Date: Sat, 15 Jul 2017 16:15:03 -0400
Subject: [PATCH] new site generation foundation in place, now need the meta
 parser and include directives

---
 site/4ed_abstract_document.cpp     | 317 ++++++++++++++++-------------
 site/4ed_sitegen.cpp               |   2 +-
 site/source_material/docs.txt      |   4 +-
 site/source_material/tutorials.txt |   8 +-
 string/4coder_string_build_num.txt |   2 +-
 5 files changed, 185 insertions(+), 148 deletions(-)

diff --git a/site/4ed_abstract_document.cpp b/site/4ed_abstract_document.cpp
index 7f2e801a..4519b864 100644
--- a/site/4ed_abstract_document.cpp
+++ b/site/4ed_abstract_document.cpp
@@ -18,15 +18,8 @@ struct Enriched_Text{
 internal Enriched_Text
 load_enriched_text(char *directory, char *filename){
     Enriched_Text result = {0};
-    
-    char space[256];
-    String fname = make_fixed_width_string(space);
-    append(&fname, directory);
-    append(&fname, "/");
-    append(&fname, filename);
-    terminate_with_null(&fname);
-    
-    result.source = file_dump(fname.str);
+    char *fname = fm_str(directory, "/", filename);
+    result.source = file_dump(fname);
     return(result);
 }
 
@@ -35,6 +28,7 @@ load_enriched_text(char *directory, char *filename){
 enum{
     Doc_Root,
     Doc_Section,
+    Doc_Error,
     Doc_Todo,
     Doc_Include,
     Doc_DocList,
@@ -51,8 +45,6 @@ enum{
     Doc_Video,
     Doc_BeginParagraph,
     Doc_EndParagraph,
-    Doc_BeginSection,
-    Doc_EndSection,
     Doc_BeginList,
     Doc_EndList,
     Doc_BeginItem,
@@ -86,7 +78,7 @@ struct Document_Item{
             Document_Item *last_child;
             String name;
             String id;
-            i32 show_title;
+            b32 show_title;
         } section;
         
         struct{
@@ -254,36 +246,6 @@ add_image_instantiation(Basic_List *list, i32 w, i32 h){
     instantiation->h = h;
 }
 
-internal void
-set_section_name(Document_Item *item, char *name, i32 show_title){
-    i32 name_len = str_size(name);
-    item->section.name = make_string_cap(fm_push_array(char, name_len+1), 0, name_len+1);
-    fm_align();
-    append(&item->section.name, name);
-    item->section.show_title = show_title;
-}
-
-internal void
-set_section_id(Document_Item *item, char *id){
-    i32 id_len = str_size(id);
-    item->section.id = make_string_cap(fm_push_array(char, id_len+1), 0, id_len+1);
-    fm_align();
-    append(&item->section.id, id);
-}
-
-internal void
-begin_document_description(Abstract_Item *doc, char *title, i32 show_title){
-    *doc = null_abstract_item;
-    doc->item_type = ItemType_Document;
-    
-    doc->root_item = fm_push_array(Document_Item, 1);
-    *doc->root_item = null_document_item;
-    doc->section_stack[doc->section_top] = doc->root_item;
-    doc->root_item->type = Doc_Root;
-    
-    set_section_name(doc->root_item, title, show_title);
-}
-
 internal Abstract_Item*
 add_generic_file(Document_System *system, char *source_file, char *extension, char *name){
     Abstract_Item *item = create_item(&system->file_list, name);
@@ -320,8 +282,38 @@ add_image_description(Document_System *system, char *source_file, char *extensio
     return(item);
 }
 
+internal void
+set_section_name(Document_Item *item, char *name, b32 show_title){
+    i32 name_len = str_size(name);
+    item->section.name = str_alloc(name_len + 1);
+    fm_align();
+    append(&item->section.name, name);
+    item->section.show_title = show_title;
+}
+
+internal void
+set_section_id(Document_Item *item, char *id){
+    i32 id_len = str_size(id);
+    item->section.id = str_alloc(id_len + 1);
+    fm_align();
+    append(&item->section.id, id);
+}
+
+internal void
+begin_document_description(Abstract_Item *doc, char *title, b32 show_title){
+    *doc = null_abstract_item;
+    doc->item_type = ItemType_Document;
+    
+    doc->root_item = fm_push_array(Document_Item, 1);
+    *doc->root_item = null_document_item;
+    doc->section_stack[doc->section_top] = doc->root_item;
+    doc->root_item->type = Doc_Root;
+    
+    set_section_name(doc->root_item, title, show_title);
+}
+
 internal Abstract_Item*
-begin_document_description(Document_System *system, char *title, char *name, i32 show_title){
+begin_document_description(Document_System *system, char *title, char *name, b32 show_title){
     Abstract_Item *item = create_item(&system->doc_list, name);
     if (item){
         begin_document_description(item, title, show_title);
@@ -359,7 +351,7 @@ begin_section(Abstract_Item *item, char *title, char *id){
     
     section->type = Doc_Section;
     
-    set_section_name(section, title, 1);
+    set_section_name(section, title, true);
     if (id != 0){
         set_section_id(section, id);
     }
@@ -373,6 +365,29 @@ end_section(Abstract_Item *doc){
     --doc->section_top;
 }
 
+internal void
+add_error(Abstract_Item *doc, String text){
+    Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
+    Document_Item *parent = doc->section_stack[doc->section_top];
+    Document_Item *item = fm_push_array(Document_Item, 1);
+    *item = null_document_item;
+    item->type = Doc_Error;
+    item->string.string = str_alloc(text.size);
+    fm_align();
+    copy(&item->string.string, text);
+    
+    append_child(parent, item);
+}
+
+internal void
+report_error_missing_body(Abstract_Item *doc, String command_body){
+    char space[512];
+    String error_string = make_fixed_width_string(space);
+    append(&error_string, "missing body for ");
+    append(&error_string, command_body);
+    add_error(doc, error_string);
+}
+
 internal void
 add_todo(Abstract_Item *doc){
     Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
@@ -455,6 +470,7 @@ add_plain_old_text(Abstract_Item *doc, String text){
     *item = null_document_item;
     item->type = Doc_PlainOldText;
     item->string.string = str_alloc(text.size);
+    fm_align();
     copy(&item->string.string, text);
     
     append_child(parent, item);
@@ -491,6 +507,7 @@ add_begin_style(Abstract_Item *doc, String text){
     *item = null_document_item;
     item->type = Doc_BeginStyle;
     item->string.string = str_alloc(text.size);
+    fm_align();
     copy(&item->string.string, text);
     
     append_child(parent, item);
@@ -515,6 +532,7 @@ add_document_link(Abstract_Item *doc, String text){
     *item = null_document_item;
     item->type = Doc_DocumentLink;
     item->string.string = str_alloc(text.size);
+    fm_align();
     copy(&item->string.string, text);
     
     append_child(parent, item);
@@ -528,6 +546,7 @@ add_begin_link(Abstract_Item *doc, String text){
     *item = null_document_item;
     item->type = Doc_BeginLink;
     item->string.string = str_alloc(text.size);
+    fm_align();
     copy(&item->string.string, text);
     
     append_child(parent, item);
@@ -552,9 +571,11 @@ add_image(Abstract_Item *doc, String text, String extra_text){
     *item = null_document_item;
     item->type = Doc_Image;
     item->string.string = str_alloc(text.size);
+    fm_align();
     copy(&item->string.string, text);
     if (extra_text.size > 0){
         item->string.string2 = str_alloc(extra_text.size);
+        fm_align();
         copy(&item->string.string2, extra_text);
     }
     
@@ -569,6 +590,7 @@ add_video(Abstract_Item *doc, String text){
     *item = null_document_item;
     item->type = Doc_Video;
     item->string.string = str_alloc(text.size);
+    fm_align();
     copy(&item->string.string, text);
     
     append_child(parent, item);
@@ -596,30 +618,6 @@ add_end_paragraph(Abstract_Item *doc){
     append_child(parent, item);
 }
 
-internal void
-add_begin_section(Abstract_Item *doc, String text){
-    Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
-    Document_Item *parent = doc->section_stack[doc->section_top];
-    Document_Item *item = fm_push_array(Document_Item, 1);
-    *item = null_document_item;
-    item->type = Doc_BeginSection;
-    item->string.string = str_alloc(text.size);
-    copy(&item->string.string, text);
-    
-    append_child(parent, item);
-}
-
-internal void
-add_end_section(Abstract_Item *doc){
-    Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
-    Document_Item *parent = doc->section_stack[doc->section_top];
-    Document_Item *item = fm_push_array(Document_Item, 1);
-    *item = null_document_item;
-    item->type = Doc_EndSection;
-    
-    append_child(parent, item);
-}
-
 internal void
 add_begin_list(Abstract_Item *doc){
     Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
@@ -682,6 +680,8 @@ enum Command_Types{
     Cmd_Section,
     Cmd_EndSection,
     Cmd_Version,
+    Cmd_TableOfContents,
+    Cmd_Todo,
     // never below this
     Cmd_COUNT,
 };
@@ -696,7 +696,7 @@ get_enriched_commands(){
         enriched_commands_global_array[Cmd_BackSlash]       = make_lit_string("\\");
         enriched_commands_global_array[Cmd_BeginStyle]      = make_lit_string("BEGIN_STYLE");
         enriched_commands_global_array[Cmd_EndStyle]        = make_lit_string("END_STYLE");
-        enriched_commands_global_array[Cmd_DocumentLink]         = make_lit_string("DOC_LINK");
+        enriched_commands_global_array[Cmd_DocumentLink]    = make_lit_string("DOC_LINK");
         enriched_commands_global_array[Cmd_BeginList]       = make_lit_string("BEGIN_LIST");
         enriched_commands_global_array[Cmd_EndList]         = make_lit_string("END_LIST");
         enriched_commands_global_array[Cmd_BeginItem]       = make_lit_string("BEGIN_ITEM");
@@ -708,6 +708,8 @@ get_enriched_commands(){
         enriched_commands_global_array[Cmd_Section]         = make_lit_string("SECTION");
         enriched_commands_global_array[Cmd_EndSection]      = make_lit_string("END_SECTION");
         enriched_commands_global_array[Cmd_Version]         = make_lit_string("VERSION");
+        enriched_commands_global_array[Cmd_TableOfContents] = make_lit_string("TABLE_OF_CONTENTS");
+        enriched_commands_global_array[Cmd_Todo]            = make_lit_string("TODO");
     }
     return(enriched_commands_global_array);
 }
@@ -765,12 +767,14 @@ extract_command_body(String l, i32 *i_in_out, String *body_text_out){
 internal Abstract_Item*
 make_document_from_text(Document_System *doc_system, char *title, char *name, Enriched_Text *text){
     String source = text->source;
-    Abstract_Item *doc = begin_document_description(doc_system, title, name, 0);
+    Abstract_Item *doc = begin_document_description(doc_system, title, name, false);
     
     for (String line = get_first_double_line(source);
          line.str;
          line = get_next_double_line(source, line)){
         String l = skip_chop_whitespace(line);
+        if (l.size == 0) continue;
+        
         add_begin_paragraph(doc);
         
         i32 start = 0, i = 0;
@@ -819,7 +823,7 @@ make_document_from_text(Document_System *doc_system, char *title, char *name, En
                             add_begin_style(doc, body_text);
                         }
                         else{
-                            // TODO(allen): 
+                            report_error_missing_body(doc, command_string);
                         }
                     }break;
                     
@@ -837,7 +841,7 @@ make_document_from_text(Document_System *doc_system, char *title, char *name, En
                             add_document_link(doc, body_text);
                         }
                         else{
-                            // TODO(allen): 
+                            report_error_missing_body(doc, command_string);
                         }
                     }break;
                     
@@ -869,7 +873,7 @@ make_document_from_text(Document_System *doc_system, char *title, char *name, En
                             add_begin_link(doc, body_text);
                         }
                         else{
-                            // TODO(allen): 
+                            report_error_missing_body(doc, command_string);
                         }
                     }break;
                     
@@ -888,7 +892,7 @@ make_document_from_text(Document_System *doc_system, char *title, char *name, En
                             add_image(doc, body_text, size_parameter);
                         }
                         else{
-                            // TODO(allen): 
+                            report_error_missing_body(doc, command_string);
                         }
                     }break;
                     
@@ -900,7 +904,7 @@ make_document_from_text(Document_System *doc_system, char *title, char *name, En
                             add_video(doc, body_text);
                         }
                         else{
-                            // TODO(allen): 
+                            report_error_missing_body(doc, command_string);
                         }
                     }break;
                     
@@ -911,16 +915,25 @@ make_document_from_text(Document_System *doc_system, char *title, char *name, En
                         if (has_body){
                             String extra_text = {0};
                             extract_command_body(l, &i, &extra_text);
-                            add_begin_section(doc, body_text);
+                            
+                            String title = str_alloc(body_text.size + 1);
+                            copy(&title, body_text);
+                            terminate_with_null(&title);
+                            
+                            String id = str_alloc(extra_text.size + 1);
+                            copy(&id, extra_text);
+                            terminate_with_null(&id);
+                            
+                            begin_section(doc, title.str, id.str);
                         }
                         else{
-                            // TODO(allen): 
+                            report_error_missing_body(doc, command_string);
                         }
                     }break;
                     
                     case Cmd_EndSection:
                     {
-                        add_end_section(doc);
+                        end_section(doc);
                     }break;
                     
                     case Cmd_Version:
@@ -928,14 +941,34 @@ make_document_from_text(Document_System *doc_system, char *title, char *name, En
                         add_version(doc);
                     }break;
                     
+                    case Cmd_TableOfContents:
+                    {
+                        add_table_of_contents(doc);
+                    }break;
+                    
+                    case Cmd_Todo:
+                    {
+                        add_todo(doc);
+                    }break;
+                    
                     default:
                     {
-                        // TODO(allen): 
+                        char space[512];
+                        String error = make_fixed_width_string(space);
+                        append(&error, "unrecognized command ");
+                        append(&error, command_string);
+                        add_error(doc, error);
                     }break;
                 }
+                
+                start = i;
             }
         }
         
+        if (start != i){
+            add_plain_old_text(doc, substr(l, start, i - start));
+        }
+        
         add_end_paragraph(doc);
     }
     
@@ -1029,14 +1062,24 @@ append_section_number(String *out, Section_Counter *section_counter){
     append_section_number_reduced(out, section_counter, 0);
 }
 
+#define ERROR_HTML_START "<span style='color:#F00'>! generator error: "
+#define ERROR_HTML_END   " !</span>"
+
+internal void
+output_error(String *out, String error){
+    append(out, ERROR_HTML_START);
+    append(out, error);
+    append(out, ERROR_HTML_END);
+    fprintf(stdout, "error: %.*s\n", error.size, error.str);
+}
+
 internal void
 report_error_html_missing_body(String *out, String command_name){
-#define STR_START "<span style='color:#F00'>! Doc generator error: missing body for "
-#define STR_SLOW  " !</span>"
-    append(out, STR_START);
-    append(out, command_name);
-    append(out, STR_SLOW);
-    fprintf(stdout, "error: missing body for %.*s\n", command_name.size, command_name.str);
+    char space[512];
+    String str = make_fixed_width_string(space);
+    append(&str, "missing body for ");
+    append(&str, command_name);
+    output_error(out, str);
 }
 
 internal void
@@ -1074,11 +1117,10 @@ html_render_section_header(String *out, String section_name, String section_id,
 #define HTML_WIDTH 800
 
 internal void
-output_plain_old_text(String *out, char *text, u32 length){
-    String l = make_string(text, length);
+output_plain_old_text(String *out, String l){
     u32 start = 0;
     u32 i = 0;
-    for (; i < length; ++i){
+    for (; i < (u32)l.size; ++i){
         char ch = l.str[i];
         switch (ch){
             case '<':
@@ -1102,13 +1144,13 @@ output_plain_old_text(String *out, char *text, u32 length){
 }
 
 internal void
-output_begin_style(String *out, char *name, u32 length){
-    String l = make_string(name, length);
+output_begin_style(String *out, String l){
     if (match(l, "code")){
         append(out, "<span style='"HTML_CODE_STYLE"'>");
     }
     else{
         fprintf(stdout, "error: unrecognized style\n");
+        append(out, "<span>");
     }
 }
 
@@ -1118,8 +1160,7 @@ output_end_style(String *out){
 }
 
 internal void
-output_document_link(String *out, char *name, u32 length){
-    String l = make_string(name, length);
+output_document_link(String *out, String l){
     append(out, "<a href='#");
     append(out, l);
     append(out, "_doc'>");
@@ -1128,8 +1169,7 @@ output_document_link(String *out, char *name, u32 length){
 }
 
 internal void
-output_begin_link(Document_System *doc_system, String *out, char *name, u32 length){
-    String l = make_string(name, length);
+output_begin_link(Document_System *doc_system, String *out, String l){
     append(out, "<a ");
     if (l.str[0] == '!'){
         append(out, "target='_blank' ");
@@ -1162,10 +1202,7 @@ output_end_link(String *out){
 }
 
 internal void
-output_image(Document_System *doc_system, String *out, char *name, u32 length, char *name2, u32 length2){
-    String l = make_string(name, length);
-    String l2 = make_string(name2, length2);
-    
+output_image(Document_System *doc_system, String *out, String l, String l2){
     i32 pixel_height = 10;
     i32 pixel_width = HTML_WIDTH;
     
@@ -1206,9 +1243,7 @@ output_image(Document_System *doc_system, String *out, char *name, u32 length, c
 }
 
 internal void
-output_video(String *out, char *name, u32 length){
-    String l = make_string(name, length);
-    
+output_video(String *out, String l){
     if (match_part_sc(l, "youtube:")){
         i32 pixel_width = HTML_WIDTH;
         i32 pixel_height = (i32)(pixel_width * 0.5625f);
@@ -1219,13 +1254,16 @@ output_video(String *out, char *name, u32 length){
         append_int_to_str(out, pixel_width);
         append(out, "' height='");
         append_int_to_str(out, pixel_height);
-        append(out, "' src='");
+        append(out, "' src='https://www.youtube.com/embed/");
         append(out, youtube_str);
         append(out, "' allowfullscreen> </iframe>");
     }
     else{
-        append(out, "<span style='color:#F00'>! Doc generator error: unrecognized video type !</span>");
-        fprintf(stdout, "error: unrecognized video type %.*s\n", l.size, l.str);
+        char space[512];
+        String str = make_fixed_width_string(space);
+        append(&str, "unrecognized video type ");
+        append(&str, l);
+        output_error(out, str);
     }
 }
 
@@ -1240,9 +1278,8 @@ output_end_paragraph(String *out){
 }
 
 internal void
-output_begin_section(String *out, Section_Counter *section_counter, char *name, u32 length){
-    String l = make_string(name, length);
-    html_render_section_header(out, l, null_string, section_counter);
+output_begin_section(String *out, Section_Counter *section_counter, String l, String l2){
+    html_render_section_header(out, l, l2, section_counter);
     ++section_counter->nest_level;
     section_counter->list_item_counter = 0;
 }
@@ -1254,8 +1291,7 @@ output_end_section(String *out, Section_Counter *section_counter){
         ++section_counter->counter[section_counter->nest_level];
     }
     else{
-        append(out, "<span style='color:#F00'>! Doc generator error: unmatched section end !</span>");
-        fprintf(stdout, "error: unmatched section end\n");
+        output_error(out, make_lit_string("unmatched section end"));
     }
 }
 
@@ -1302,7 +1338,7 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_
         for (; i < l.size; ++i){
             char ch = l.str[i];
             if (ch == '\\'){
-                output_plain_old_text(out, l.str + start, i - start);
+                output_plain_old_text(out, substr(l, start, i - start));
                 
                 i32 command_start = i + 1;
                 i32 command_end = command_start;
@@ -1338,7 +1374,7 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_
                         String body_text = {0};
                         b32 has_body = extract_command_body(l, &i, &body_text);
                         if (has_body){
-                            output_begin_style(out, body_text.str, body_text.size);
+                            output_begin_style(out, body_text);
                         }
                         else{
                             report_error_html_missing_body(out, command_string);
@@ -1356,7 +1392,7 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_
                         String body_text = {0};
                         b32 has_body = extract_command_body(l, &i, &body_text);
                         if (has_body){
-                            output_document_link(out, body_text.str, body_text.size);
+                            output_document_link(out, body_text);
                         }
                         else{
                             report_error_html_missing_body(out, command_string);
@@ -1388,7 +1424,7 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_
                         String body_text = {0};
                         b32 has_body = extract_command_body(l, &i, &body_text);
                         if (has_body){
-                            output_begin_link(doc_system, out, body_text.str, body_text.size);
+                            output_begin_link(doc_system, out, body_text);
                         }
                         else{
                             report_error_html_missing_body(out, command_string);
@@ -1407,7 +1443,7 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_
                         if (has_body){
                             String size_parameter = {0};
                             extract_command_body(l, &i, &size_parameter);
-                            output_image(doc_system, out, body_text.str, body_text.size, size_parameter.str, size_parameter.size);
+                            output_image(doc_system, out, body_text, size_parameter);
                         }
                         else{
                             report_error_html_missing_body(out, command_string);
@@ -1419,7 +1455,7 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_
                         String body_text = {0};
                         b32 has_body = extract_command_body(l, &i, &body_text);
                         if (has_body){
-                            output_video(out, body_text.str, body_text.size);
+                            output_video(out, body_text);
                         }
                         else{
                             report_error_html_missing_body(out, command_string);
@@ -1433,7 +1469,7 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_
                         if (has_body){
                             String extra_text = {0};
                             extract_command_body(l, &i, &extra_text);
-                            output_begin_section(out, section_counter, body_text.str, body_text.size);
+                            output_begin_section(out, section_counter, body_text, extra_text);
                         }
                         else{
                             report_error_html_missing_body(out, command_string);
@@ -1450,10 +1486,19 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_
                         append(out, VERSION);
                     }break;
                     
+                    case Cmd_TableOfContents:
+                    {
+                        String str = make_lit_string("Cmd_TableOfContents does not work in this system");
+                        output_error(out, str);
+                    }break;
+                    
                     default:
                     {
-                        append(out, "<span style='color:#F00'>! Doc generator error: unrecognized command !</span>");
-                        fprintf(stdout, "error: unrecognized command %.*s\n", command_string.size, command_string.str);
+                        char space[512];
+                        String str = make_fixed_width_string(space);
+                        append(&str, "unrecognized command ");
+                        append(&str, command_string);
+                        output_error(out, str);
                     }break;
                 }
                 
@@ -1462,7 +1507,7 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_
         }
         
         if (start != i){
-            output_plain_old_text(out, l.str + start, i - start);
+            output_plain_old_text(out, substr(l, start, i - start));
         }
         
         output_end_paragraph(out);
@@ -2162,6 +2207,13 @@ doc_item_html(String *out, Document_System *doc_system, Used_Links *used_links,
             }
         }break;
         
+        case Doc_Error:
+        {
+            if (head){
+                output_error(out, item->string.string);
+            }
+        }break;
+        
         case Doc_Todo:
         {
             if (head){
@@ -2272,7 +2324,7 @@ doc_item_html(String *out, Document_System *doc_system, Used_Links *used_links,
         case Doc_PlainOldText:
         {
             if (head){
-                output_plain_old_text(out, item->string.string.str, item->string.string.size);
+                output_plain_old_text(out, item->string.string);
             }
         }break;
         
@@ -2286,7 +2338,7 @@ doc_item_html(String *out, Document_System *doc_system, Used_Links *used_links,
         case Doc_BeginStyle:
         {
             if (head){
-                output_begin_style(out, item->string.string.str, item->string.string.size);
+                output_begin_style(out, item->string.string);
             }
         }break;
         
@@ -2300,14 +2352,14 @@ doc_item_html(String *out, Document_System *doc_system, Used_Links *used_links,
         case Doc_DocumentLink:
         {
             if (head){
-                output_document_link(out, item->string.string.str, item->string.string.size);
+                output_document_link(out, item->string.string);
             }
         }break;
         
         case Doc_BeginLink:
         {
             if (head){
-                output_begin_link(doc_system, out, item->string.string.str, item->string.string.size);
+                output_begin_link(doc_system, out, item->string.string);
             }
         }break;
         
@@ -2321,14 +2373,14 @@ doc_item_html(String *out, Document_System *doc_system, Used_Links *used_links,
         case Doc_Image:
         {
             if (head){
-                output_image(doc_system, out, item->string.string.str, item->string.string.size, item->string.string2.str, item->string.string2.size);
+                output_image(doc_system, out, item->string.string, item->string.string2);
             }
         }break;
         
         case Doc_Video:
         {
             if (head){
-                output_video(out, item->string.string.str, item->string.string.size);
+                output_video(out, item->string.string);
             }
         }break;
         
@@ -2346,21 +2398,6 @@ doc_item_html(String *out, Document_System *doc_system, Used_Links *used_links,
             }
         }break;
         
-        // HACK(allen): There is also a Doc_Section type item where the section is actually a parent to the children and begin/end are handled by the one item.  That should be the only type.
-        case Doc_BeginSection:
-        {
-            if (head){
-                output_begin_section(out, section_counter, item->string.string.str, item->string.string.size);
-            }
-        }break;
-        
-        case Doc_EndSection:
-        {
-            if (head){
-                output_end_section(out, section_counter);
-            }
-        }break;
-        
         case Doc_BeginList:
         {
             if (head){
diff --git a/site/4ed_sitegen.cpp b/site/4ed_sitegen.cpp
index 086ee85c..571577cf 100644
--- a/site/4ed_sitegen.cpp
+++ b/site/4ed_sitegen.cpp
@@ -109,7 +109,7 @@ generate_4coder_docs(Document_System *doc_system, char *code_directory, char *sr
     *lexer_introduction = load_enriched_text(src_directory, "lexer_introduction.txt");
     
     // NOTE(allen): Put together the abstract document
-    Abstract_Item *doc = begin_document_description(doc_system, "4coder API Docs", "custom_docs", 1);
+    Abstract_Item *doc = begin_document_description(doc_system, "4coder API Docs", "custom_docs", true);
     
     add_table_of_contents(doc);
     
diff --git a/site/source_material/docs.txt b/site/source_material/docs.txt
index dc7df435..d9debc3a 100644
--- a/site/source_material/docs.txt
+++ b/site/source_material/docs.txt
@@ -38,7 +38,7 @@
  \END_SECTION
 \END_SECTION
 
-\SECTION{String Library}
+\SECTION{String Library}{string_library}
  \SECTION{String Library Intro}
   \TODO
  \END_SECTION
@@ -52,7 +52,7 @@
  \END_SECTION
 \END_SECTION
 
-\SECTION{Lexer Library}
+\SECTION{Lexer Library}{lexer_library}
  \SECTION{Lexer Intro}
   \INCLUDE{lexer_introduction.txt}
  \END_SECTION
diff --git a/site/source_material/tutorials.txt b/site/source_material/tutorials.txt
index c96864da..321d38f2 100644
--- a/site/source_material/tutorials.txt
+++ b/site/source_material/tutorials.txt
@@ -5,19 +5,19 @@
 
 Getting started with 4coder and navigating your files:
 
-\VIDEO{youtube:https://www.youtube.com/embed/h5cbOcnSrcc}
+\VIDEO{youtube:h5cbOcnSrcc}
 
 Setting up and navigating your project with 4coder:
 
-\VIDEO{youtube:https://www.youtube.com/embed/glPEpaT6GH0}
+\VIDEO{youtube:glPEpaT6GH0}
 
 Extending your project with a project.4coder file:
 
-\VIDEO{youtube:https://www.youtube.com/embed/iZLtS3IoatE}
+\VIDEO{youtube:iZLtS3IoatE}
 
 Using customizable keywords in the 4coder custom API:
 
-\VIDEO{youtube:https://www.youtube.com/watch?v=qoEvc4uC9Uw}
+\VIDEO{youtube:qoEvc4uC9Uw}
 
 More tutorials coming soon.
 
diff --git a/string/4coder_string_build_num.txt b/string/4coder_string_build_num.txt
index 694ecf9f..0a5554c6 100644
--- a/string/4coder_string_build_num.txt
+++ b/string/4coder_string_build_num.txt
@@ -1,5 +1,5 @@
 1
 0
-101
+102