diff --git a/site/4ed_abstract_document.cpp b/site/4ed_abstract_document.cpp index 6ea0da8d..7f2e801a 100644 --- a/site/4ed_abstract_document.cpp +++ b/site/4ed_abstract_document.cpp @@ -44,6 +44,7 @@ enum{ Doc_Version, Doc_BeginStyle, Doc_EndStyle, + Doc_DocumentLink, Doc_BeginLink, Doc_EndLink, Doc_Image, @@ -506,6 +507,19 @@ add_end_style(Abstract_Item *doc){ append_child(parent, item); } +internal void +add_document_link(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_DocumentLink; + item->string.string = str_alloc(text.size); + copy(&item->string.string, text); + + append_child(parent, item); +} + internal void add_begin_link(Abstract_Item *doc, String text){ Assert(doc->section_top + 1 < ArrayCount(doc->section_stack)); @@ -650,6 +664,285 @@ add_end_item(Abstract_Item *doc){ append_child(parent, item); } +// Document Generation from Enriched Text + +enum Command_Types{ + Cmd_BackSlash, + Cmd_BeginStyle, + Cmd_EndStyle, + Cmd_DocumentLink, + Cmd_BeginList, + Cmd_EndList, + Cmd_BeginItem, + Cmd_EndItem, + Cmd_BeginLink, + Cmd_EndLink, + Cmd_Image, + Cmd_Video, + Cmd_Section, + Cmd_EndSection, + Cmd_Version, + // never below this + Cmd_COUNT, +}; + +global b32 did_enriched_commands = false; +global String enriched_commands_global_array[Cmd_COUNT]; + +internal String* +get_enriched_commands(){ + if (!did_enriched_commands){ + did_enriched_commands = true; + 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_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"); + enriched_commands_global_array[Cmd_EndItem] = make_lit_string("END_ITEM"); + enriched_commands_global_array[Cmd_BeginLink] = make_lit_string("BEGIN_LINK"); + enriched_commands_global_array[Cmd_EndLink] = make_lit_string("END_LINK"); + enriched_commands_global_array[Cmd_Image] = make_lit_string("IMAGE"); + enriched_commands_global_array[Cmd_Video] = make_lit_string("VIDEO"); + 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"); + } + return(enriched_commands_global_array); +} + +internal u32 +get_enriched_commands_count(){ + return(ArrayCount(enriched_commands_global_array)); +} + +internal b32 +extract_command_body(String l, i32 *i_in_out, i32 *body_start_out, i32 *body_end_out){ + b32 result = false; + i32 i = *i_in_out; + + for (; i < l.size; ++i){ + if (!char_is_whitespace(l.str[i])){ + break; + } + } + + i32 body_start = 0, body_end = 0; + if (l.str[i] == '{'){ + body_start = i + 1; + for (++i; i < l.size; ++i){ + if (l.str[i] == '}'){ + result = true; + body_end = i; + ++i; + break; + } + } + } + + if (result){ + *i_in_out = i; + *body_start_out = body_start; + *body_end_out = body_end; + } + + return(result); +} + +internal b32 +extract_command_body(String l, i32 *i_in_out, String *body_text_out){ + i32 body_start = 0, body_end = 0; + b32 has_body = extract_command_body(l, i_in_out, &body_start, &body_end); + if (has_body){ + String body_text = substr(l, body_start, body_end - body_start); + body_text = skip_chop_whitespace(body_text); + *body_text_out = body_text; + } + return(has_body); +} + +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); + + for (String line = get_first_double_line(source); + line.str; + line = get_next_double_line(source, line)){ + String l = skip_chop_whitespace(line); + add_begin_paragraph(doc); + + i32 start = 0, i = 0; + for (; i < l.size; ++i){ + char ch = l.str[i]; + if (ch == '\\'){ + add_plain_old_text(doc, substr(l, start, i - start)); + + i32 command_start = i + 1; + i32 command_end = command_start; + for (; command_end < l.size; ++command_end){ + if (!char_is_alpha_numeric(l.str[command_end])){ + break; + } + } + + if (command_end == command_start){ + if (command_end < l.size && l.str[command_end] == '\\'){ + ++command_end; + } + } + + String command_string = substr(l, command_start, command_end - command_start); + + String *enriched_commands = get_enriched_commands(); + u32 enriched_commands_count = get_enriched_commands_count(); + + i = command_end; + + i32 match_index = 0; + if (!string_set_match(enriched_commands, enriched_commands_count, command_string, &match_index)){ + match_index = -1; + } + + switch (match_index){ + case Cmd_BackSlash: + { + add_plain_old_text(doc, make_lit_string("\\")); + }break; + + case Cmd_BeginStyle: + { + String body_text = {0}; + b32 has_body = extract_command_body(l, &i, &body_text); + if (has_body){ + add_begin_style(doc, body_text); + } + else{ + // TODO(allen): + } + }break; + + case Cmd_EndStyle: + { + add_end_style(doc); + }break; + + // TODO(allen): upgrade this bs + case Cmd_DocumentLink: + { + String body_text = {0}; + b32 has_body = extract_command_body(l, &i, &body_text); + if (has_body){ + add_document_link(doc, body_text); + } + else{ + // TODO(allen): + } + }break; + + case Cmd_BeginList: + { + add_begin_list(doc); + }break; + + case Cmd_EndList: + { + add_end_list(doc); + }break; + + case Cmd_BeginItem: + { + add_begin_item(doc); + }break; + + case Cmd_EndItem: + { + add_end_item(doc); + }break; + + case Cmd_BeginLink: + { + String body_text = {0}; + b32 has_body = extract_command_body(l, &i, &body_text); + if (has_body){ + add_begin_link(doc, body_text); + } + else{ + // TODO(allen): + } + }break; + + case Cmd_EndLink: + { + add_end_link(doc); + }break; + + case Cmd_Image: + { + String body_text = {0}; + b32 has_body = extract_command_body(l, &i, &body_text); + if (has_body){ + String size_parameter = {0}; + extract_command_body(l, &i, &size_parameter); + add_image(doc, body_text, size_parameter); + } + else{ + // TODO(allen): + } + }break; + + case Cmd_Video: + { + String body_text = {0}; + b32 has_body = extract_command_body(l, &i, &body_text); + if (has_body){ + add_video(doc, body_text); + } + else{ + // TODO(allen): + } + }break; + + case Cmd_Section: + { + String body_text = {0}; + b32 has_body = extract_command_body(l, &i, &body_text); + if (has_body){ + String extra_text = {0}; + extract_command_body(l, &i, &extra_text); + add_begin_section(doc, body_text); + } + else{ + // TODO(allen): + } + }break; + + case Cmd_EndSection: + { + add_end_section(doc); + }break; + + case Cmd_Version: + { + add_version(doc); + }break; + + default: + { + // TODO(allen): + }break; + } + } + } + + add_end_paragraph(doc); + } + + end_document_description(doc); + return(doc); +} + // HTML Document Generation #define HTML_BACK_COLOR "#FAFAFA" @@ -736,60 +1029,14 @@ append_section_number(String *out, Section_Counter *section_counter){ append_section_number_reduced(out, section_counter, 0); } -internal b32 -extract_command_body(String *out, String l, i32 *i_in_out, i32 *body_start_out, i32 *body_end_out, String command_name, b32 require_body){ - b32 result = false; - - i32 i = *i_in_out; - - for (; i < l.size; ++i){ - if (!char_is_whitespace(l.str[i])){ - break; - } - } - - i32 body_start = 0, body_end = 0; - if (l.str[i] == '{'){ - body_start = i + 1; - - for (++i; i < l.size; ++i){ - if (l.str[i] == '}'){ - result = true; - body_end = i; - ++i; - break; - } - } - } - - if (!result && require_body){ +internal void +report_error_html_missing_body(String *out, String command_name){ #define STR_START "! Doc generator error: missing body for " -#define STR_SLOW " !" - 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); - } - - if (result){ - *i_in_out = i; - *body_start_out = body_start; - *body_end_out = body_end; - } - - return(result); -} - -internal b32 -extract_command_body(String *out, String l, i32 *i_in_out, String *body_text_out, String command_name, b32 require_body){ - i32 body_start = 0, body_end = 0; - b32 has_body = extract_command_body(out, l, i_in_out, &body_start, &body_end, command_name, require_body); - if (has_body){ - String body_text = substr(l, body_start, body_end - body_start); - body_text = skip_chop_whitespace(body_text); - *body_text_out = body_text; - } - return(has_body); +#define STR_SLOW " !" + 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); } internal void @@ -826,61 +1073,6 @@ html_render_section_header(String *out, String section_name, String section_id, #define HTML_WIDTH 800 -enum Command_Types{ - Cmd_BackSlash, - Cmd_DoMetaParse, - Cmd_Version, - Cmd_BeginStyle, - Cmd_EndStyle, - Cmd_DocLink, - Cmd_BeginList, - Cmd_EndList, - Cmd_BeginItem, - Cmd_EndItem, - Cmd_BeginLink, - Cmd_EndLink, - Cmd_Image, - Cmd_Video, - Cmd_Section, - Cmd_EndSection, - Cmd_TableOfContents, - // never below this - Cmd_COUNT, -}; - -global b32 did_enriched_commands = false; -global String enriched_commands_global_array[Cmd_COUNT]; - -internal String* -get_enriched_commands(){ - if (!did_enriched_commands){ - did_enriched_commands = true; - enriched_commands_global_array[Cmd_BackSlash] = make_lit_string("\\"); - enriched_commands_global_array[Cmd_DoMetaParse] = make_lit_string("META_PARSE"); - enriched_commands_global_array[Cmd_Version] = make_lit_string("VERSION"); - 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_DocLink] = 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"); - enriched_commands_global_array[Cmd_EndItem] = make_lit_string("END_ITEM"); - enriched_commands_global_array[Cmd_BeginLink] = make_lit_string("BEGIN_LINK"); - enriched_commands_global_array[Cmd_EndLink] = make_lit_string("END_LINK"); - enriched_commands_global_array[Cmd_Image] = make_lit_string("IMAGE"); - enriched_commands_global_array[Cmd_Video] = make_lit_string("VIDEO"); - 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_TableOfContents] = make_lit_string("TABLE_OF_CONTENTS"); - } - return(enriched_commands_global_array); -} - -internal u32 -get_enriched_commands_count(){ - return(ArrayCount(enriched_commands_global_array)); -} - internal void output_plain_old_text(String *out, char *text, u32 length){ String l = make_string(text, length); @@ -925,6 +1117,16 @@ output_end_style(String *out){ append(out, ""); } +internal void +output_document_link(String *out, char *name, u32 length){ + String l = make_string(name, length); + append(out, ""); + append(out, l); + append(out, ""); +} + internal void output_begin_link(Document_System *doc_system, String *out, char *name, u32 length){ String l = make_string(name, length); @@ -1093,7 +1295,7 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_ for (String line = get_first_double_line(source); line.str; line = get_next_double_line(source, line)){ - String l = skip_chop_whitespace(line); + String l = skip_chop_whitespace(line); output_begin_paragraph(out); i32 start = 0, i = 0; @@ -1131,20 +1333,16 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_ switch (match_index){ case Cmd_BackSlash: append(out, "\\"); break; - case Cmd_DoMetaParse: - { - fprintf(stdout, "Cmd_DoMetaParse: not implemented\n"); - }break; - - case Cmd_Version: append(out, VERSION); break; - case Cmd_BeginStyle: { String body_text = {0}; - b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true); + b32 has_body = extract_command_body(l, &i, &body_text); if (has_body){ output_begin_style(out, body_text.str, body_text.size); } + else{ + report_error_html_missing_body(out, command_string); + } }break; case Cmd_EndStyle: @@ -1153,16 +1351,15 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_ }break; // TODO(allen): upgrade this bs - case Cmd_DocLink: + case Cmd_DocumentLink: { String body_text = {0}; - b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true); + b32 has_body = extract_command_body(l, &i, &body_text); if (has_body){ - append(out, ""); - append(out, body_text); - append(out, ""); + output_document_link(out, body_text.str, body_text.size); + } + else{ + report_error_html_missing_body(out, command_string); } }break; @@ -1189,10 +1386,13 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_ case Cmd_BeginLink: { String body_text = {0}; - b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true); + 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); } + else{ + report_error_html_missing_body(out, command_string); + } }break; case Cmd_EndLink: @@ -1203,33 +1403,41 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_ case Cmd_Image: { String body_text = {0}; - b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true); + b32 has_body = extract_command_body(l, &i, &body_text); if (has_body){ String size_parameter = {0}; - extract_command_body(out, l, &i, &size_parameter, command_string, false); - + extract_command_body(l, &i, &size_parameter); output_image(doc_system, out, body_text.str, body_text.size, size_parameter.str, size_parameter.size); } + else{ + report_error_html_missing_body(out, command_string); + } }break; case Cmd_Video: { String body_text = {0}; - b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true); + b32 has_body = extract_command_body(l, &i, &body_text); if (has_body){ output_video(out, body_text.str, body_text.size); } + else{ + report_error_html_missing_body(out, command_string); + } }break; case Cmd_Section: { String body_text = {0}; - b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true); + b32 has_body = extract_command_body(l, &i, &body_text); if (has_body){ String extra_text = {0}; - extract_command_body(out, l, &i, &extra_text, command_string, false); + extract_command_body(l, &i, &extra_text); output_begin_section(out, section_counter, body_text.str, body_text.size); } + else{ + report_error_html_missing_body(out, command_string); + } }break; case Cmd_EndSection: @@ -1237,9 +1445,9 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_ output_end_section(out, section_counter); }break; - case Cmd_TableOfContents: + case Cmd_Version: { - fprintf(stdout, "Cmd_TableOfContents: not implemented\n"); + append(out, VERSION); }break; default: @@ -2089,6 +2297,13 @@ doc_item_html(String *out, Document_System *doc_system, Used_Links *used_links, } }break; + case Doc_DocumentLink: + { + if (head){ + output_document_link(out, item->string.string.str, item->string.string.size); + } + }break; + case Doc_BeginLink: { if (head){ diff --git a/site/4ed_sitegen.cpp b/site/4ed_sitegen.cpp index 08120951..38c9c4b3 100644 --- a/site/4ed_sitegen.cpp +++ b/site/4ed_sitegen.cpp @@ -230,12 +230,8 @@ generate_page(Document_System *doc_system, char *code_directory, char *src_direc Enriched_Text *home = fm_push_array(Enriched_Text, 1); *home = load_enriched_text(src_directory, source_text); - Abstract_Item *doc = begin_document_description(doc_system, big_title, small_name, 0); - if (doc != 0){ - add_enriched_text(doc, home); - end_document_description(doc); - } - else{ + Abstract_Item *doc = make_document_from_text(doc_system, big_title, small_name, home); + if (doc == 0){ fprintf(stdout, "warning: could not create document %s from file %s\n", small_name, source_text); }