taking steps towards simplifying the site generator

This commit is contained in:
Allen Webster 2017-07-13 01:02:21 -04:00
parent 4df05414f2
commit 665fc2ba35
2 changed files with 397 additions and 333 deletions

View File

@ -39,7 +39,11 @@ enum{
Doc_Enriched_Text, Doc_Enriched_Text,
Doc_Element_List, Doc_Element_List,
Doc_Full_Elements, Doc_Full_Elements,
Doc_Table_Of_Contents Doc_Table_Of_Contents,
Doc_Plain_Old_Text,
//
Doc_COUNT,
}; };
struct Alternate_Name{ struct Alternate_Name{
@ -77,8 +81,12 @@ struct Document_Item{
} unit_elements; } unit_elements;
struct{ struct{
Enriched_Text *text; String text;
} text; } text;
struct{
Enriched_Text *text;
} enriched_text;
}; };
}; };
global Document_Item null_document_item = {0}; global Document_Item null_document_item = {0};
@ -284,7 +292,7 @@ add_image_description(Document_System *system, char *source_file, char *extensio
i32 w = 0, h = 0, comp = 0; i32 w = 0, h = 0, comp = 0;
i32 stbi_r = stbi_info(source_file, &w, &h, &comp); i32 stbi_r = stbi_info(source_file, &w, &h, &comp);
if (!stbi_r){ if (!stbi_r){
fprintf(stderr, "Did not find file %s\n", source_file); fprintf(stdout, "Did not find file %s\n", source_file);
item->w_h_ratio = 1.f; item->w_h_ratio = 1.f;
item->h_w_ratio = 1.f; item->h_w_ratio = 1.f;
} }
@ -326,7 +334,7 @@ append_child(Document_Item *parent, Document_Item *item){
internal void internal void
begin_section(Abstract_Item *item, char *title, char *id){ begin_section(Abstract_Item *item, char *title, char *id){
Assert(item->section_top+1 < ArrayCount(item->section_stack)); Assert(item->section_top + 1 < ArrayCount(item->section_stack));
Document_Item *parent = item->section_stack[item->section_top]; Document_Item *parent = item->section_stack[item->section_top];
Document_Item *section = fm_push_array(Document_Item, 1); Document_Item *section = fm_push_array(Document_Item, 1);
@ -351,6 +359,7 @@ end_section(Abstract_Item *doc){
internal void internal void
add_todo(Abstract_Item *doc){ add_todo(Abstract_Item *doc){
Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top]; Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *item = fm_push_array(Document_Item, 1); Document_Item *item = fm_push_array(Document_Item, 1);
*item = null_document_item; *item = null_document_item;
@ -361,6 +370,7 @@ add_todo(Abstract_Item *doc){
internal void internal void
add_element_list(Abstract_Item *doc, Meta_Unit *unit){ add_element_list(Abstract_Item *doc, Meta_Unit *unit){
Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top]; Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *item = fm_push_array(Document_Item, 1); Document_Item *item = fm_push_array(Document_Item, 1);
*item = null_document_item; *item = null_document_item;
@ -372,6 +382,7 @@ add_element_list(Abstract_Item *doc, Meta_Unit *unit){
internal void internal void
add_element_list(Abstract_Item *doc, Meta_Unit *unit, Alternate_Names_Array *alt_names, i32 alt_name_type){ add_element_list(Abstract_Item *doc, Meta_Unit *unit, Alternate_Names_Array *alt_names, i32 alt_name_type){
Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top]; Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *item = fm_push_array(Document_Item, 1); Document_Item *item = fm_push_array(Document_Item, 1);
*item = null_document_item; *item = null_document_item;
@ -385,6 +396,7 @@ add_element_list(Abstract_Item *doc, Meta_Unit *unit, Alternate_Names_Array *alt
internal void internal void
add_full_elements(Abstract_Item *doc, Meta_Unit *unit){ add_full_elements(Abstract_Item *doc, Meta_Unit *unit){
Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top]; Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *item = fm_push_array(Document_Item, 1); Document_Item *item = fm_push_array(Document_Item, 1);
*item = null_document_item; *item = null_document_item;
@ -396,6 +408,7 @@ add_full_elements(Abstract_Item *doc, Meta_Unit *unit){
internal void internal void
add_full_elements(Abstract_Item *doc, Meta_Unit *unit, Alternate_Names_Array *alt_names, i32 alt_name_type){ add_full_elements(Abstract_Item *doc, Meta_Unit *unit, Alternate_Names_Array *alt_names, i32 alt_name_type){
Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top]; Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *item = fm_push_array(Document_Item, 1); Document_Item *item = fm_push_array(Document_Item, 1);
*item = null_document_item; *item = null_document_item;
@ -409,6 +422,7 @@ add_full_elements(Abstract_Item *doc, Meta_Unit *unit, Alternate_Names_Array *al
internal void internal void
add_table_of_contents(Abstract_Item *doc){ add_table_of_contents(Abstract_Item *doc){
Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top]; Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *item = fm_push_array(Document_Item, 1); Document_Item *item = fm_push_array(Document_Item, 1);
*item = null_document_item; *item = null_document_item;
@ -418,14 +432,26 @@ add_table_of_contents(Abstract_Item *doc){
} }
internal void internal void
add_enriched_text(Abstract_Item *doc, Enriched_Text *text){ add_plain_old_text(Abstract_Item *doc, String text){
Assert(doc->section_top+1 < ArrayCount(doc->section_stack)); 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_Plain_Old_Text;
item->text.text = str_alloc(text.size);
copy(&item->text.text, text);
append_child(parent, item);
}
internal void
add_enriched_text(Abstract_Item *doc, Enriched_Text *text){
Assert(doc->section_top + 1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top]; Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *item = fm_push_array(Document_Item, 1); Document_Item *item = fm_push_array(Document_Item, 1);
*item = null_document_item; *item = null_document_item;
item->type = Doc_Enriched_Text; item->type = Doc_Enriched_Text;
item->text.text = text; item->enriched_text.text = text;
append_child(parent, item); append_child(parent, item);
} }
@ -515,9 +541,9 @@ append_section_number(String *out, Section_Counter *section_counter){
append_section_number_reduced(out, section_counter, 0); append_section_number_reduced(out, section_counter, 0);
} }
internal i32 internal b32
extract_command_body(String *out, String l, i32 *i_in_out, i32 *body_start_out, i32 *body_end_out, String command_name, i32 require_body){ 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){
i32 result = 0; b32 result = false;
i32 i = *i_in_out; i32 i = *i_in_out;
@ -527,14 +553,13 @@ extract_command_body(String *out, String l, i32 *i_in_out, i32 *body_start_out,
} }
} }
i32 found_command_body = 0;
i32 body_start = 0, body_end = 0; i32 body_start = 0, body_end = 0;
if (l.str[i] == '{'){ if (l.str[i] == '{'){
body_start = i+1; body_start = i + 1;
for (++i; i < l.size; ++i){ for (++i; i < l.size; ++i){
if (l.str[i] == '}'){ if (l.str[i] == '}'){
found_command_body = 1; result = true;
body_end = i; body_end = i;
++i; ++i;
break; break;
@ -542,19 +567,13 @@ extract_command_body(String *out, String l, i32 *i_in_out, i32 *body_start_out,
} }
} }
if (found_command_body){ if (!result && require_body){
result = 1;
}
else{
if (require_body){
#define STR_START "<span style='color:#F00'>! Doc generator error: missing body for " #define STR_START "<span style='color:#F00'>! Doc generator error: missing body for "
#define STR_SLOW " !</span>" #define STR_SLOW " !</span>"
append(out, STR_START); append(out, STR_START);
append(out, command_name); append(out, command_name);
append(out, STR_SLOW); append(out, STR_SLOW);
#undef STR fprintf(stdout, "error: missing body for %.*s\n", command_name.size, command_name.str);
fprintf(stderr, "error: missing body for %.*s\n", command_name.size, command_name.str);
}
} }
*i_in_out = i; *i_in_out = i;
@ -564,6 +583,18 @@ extract_command_body(String *out, String l, i32 *i_in_out, i32 *body_start_out,
return(result); 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);
}
internal void internal void
html_render_section_header(String *out, String section_name, String section_id, Section_Counter *section_counter){ html_render_section_header(String *out, String section_name, String section_id, Section_Counter *section_counter){
if (section_counter->nest_level <= 1){ if (section_counter->nest_level <= 1){
@ -598,6 +629,91 @@ html_render_section_header(String *out, String section_name, String section_id,
#define HTML_WIDTH 800 #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_BoldFace,
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_BoldFace] = make_lit_string("BOLD_FACE");
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);
u32 start = 0;
u32 i = 0;
for (; i < length; ++i){
char ch = l.str[i];
switch (ch){
case '<':
{
append(out, substr(l, start, i - start));
append(out, "&lt;");
start = i + 1;
}break;
case '>':
{
append(out, substr(l, start, i - start));
append(out, "&gt;");
start = i + 1;
}break;
}
}
if (start != i){
append(out, substr(l, start, i - start));
}
}
internal void internal void
write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_system, Section_Counter *section_counter){ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_system, Section_Counter *section_counter){
String source = text->source; String source = text->source;
@ -615,313 +731,250 @@ write_enriched_text_html(String *out, Enriched_Text *text, Document_System *doc_
i32 start = 0, i = 0; i32 start = 0, i = 0;
for (; i < l.size; ++i){ for (; i < l.size; ++i){
char ch = l.str[i]; char ch = l.str[i];
switch (ch){ if (ch == '\\'){
case '<': output_plain_old_text(out, l.str + start, i - start);
{
append(out, substr(l, start, i-start));
append(out, "&lt;");
start = i+1;
}break;
case '>': i32 command_start = i + 1;
{ i32 command_end = command_start;
append(out, substr(l, start, i-start)); for (; command_end < l.size; ++command_end){
append(out, "&gt;"); if (!char_is_alpha_numeric(l.str[command_end])){
start = i+1; break;
}break;
case '\\':
{
append(out, 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 == command_start){
if (command_end < l.size && l.str[command_end] == '\\'){ if (command_end < l.size && l.str[command_end] == '\\'){
++command_end; ++command_end;
}
} }
}
String command_string = substr(l, command_start, command_end - command_start); String command_string = substr(l, command_start, command_end - command_start);
enum Command_Types{ String *enriched_commands = get_enriched_commands();
Cmd_BackSlash, u32 enriched_commands_count = get_enriched_commands_count();
Cmd_Version,
Cmd_BeginStyle,
Cmd_EndStyle,
Cmd_DocLink,
Cmd_BeginList,
Cmd_EndList,
Cmd_BeginItem,
Cmd_EndItem,
Cmd_BoldFace,
Cmd_Section,
Cmd_BeginLink,
Cmd_EndLink,
Cmd_Image,
Cmd_Video,
Cmd_EndSection,
Cmd_DoMetaParse,
// never below this
Cmd_COUNT,
};
local_persist String enriched_commands[Cmd_COUNT]; i = command_end;
enriched_commands[Cmd_BackSlash] = make_lit_string("\\"); i32 match_index = 0;
enriched_commands[Cmd_Version] = make_lit_string("VERSION"); if (!string_set_match(enriched_commands, enriched_commands_count, command_string, &match_index)){
enriched_commands[Cmd_BeginStyle] = make_lit_string("BEGIN_STYLE"); match_index = -1;
enriched_commands[Cmd_EndStyle] = make_lit_string("END_STYLE"); }
enriched_commands[Cmd_DocLink] = make_lit_string("DOC_LINK");
enriched_commands[Cmd_BeginList] = make_lit_string("BEGIN_LIST");
enriched_commands[Cmd_EndList] = make_lit_string("END_LIST");
enriched_commands[Cmd_BeginItem] = make_lit_string("BEGIN_ITEM");
enriched_commands[Cmd_EndItem] = make_lit_string("END_ITEM");
enriched_commands[Cmd_BoldFace] = make_lit_string("BOLD_FACE");
enriched_commands[Cmd_Section] = make_lit_string("SECTION");
enriched_commands[Cmd_BeginLink] = make_lit_string("BEGIN_LINK");
enriched_commands[Cmd_EndLink] = make_lit_string("END_LINK");
enriched_commands[Cmd_Image] = make_lit_string("IMAGE");
enriched_commands[Cmd_Video] = make_lit_string("VIDEO");
enriched_commands[Cmd_EndSection] = make_lit_string("END_SECTION");
enriched_commands[Cmd_DoMetaParse] = make_lit_string("META_PARSE");
i = command_end; switch (match_index){
case Cmd_BackSlash: append(out, "\\"); break;
i32 match_index = 0; case Cmd_DoMetaParse:
if (string_set_match(enriched_commands, ArrayCount(enriched_commands), command_string, &match_index)){ {
switch (match_index){ fprintf(stdout, "Cmd_DoMetaParse: not implemented\n");
case Cmd_BackSlash: append(out, "\\"); break; }break;
case Cmd_Version: append(out, VERSION); break;
case Cmd_BeginStyle: case Cmd_Version: append(out, VERSION); break;
{
i32 body_start = 0, body_end = 0;
i32 has_body = extract_command_body(out, l, &i, &body_start, &body_end, command_string, 1);
if (has_body){
String body_text = substr(l, body_start, body_end - body_start);
body_text = skip_chop_whitespace(body_text);
if (match_sc(body_text, "code")){
append(out, "<span style='"HTML_CODE_STYLE"'>");
}
}
}break;
case Cmd_EndStyle: case Cmd_BeginStyle:
{ {
append(out, "</span>"); String body_text = {0};
}break; b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true);
if (has_body){
if (match_sc(body_text, "code")){
append(out, "<span style='"HTML_CODE_STYLE"'>");
}
}
}break;
// TODO(allen): upgrade this bs case Cmd_EndStyle:
case Cmd_DocLink: {
{ append(out, "</span>");
i32 body_start = 0, body_end = 0;
i32 has_body = extract_command_body(out, l, &i, &body_start, &body_end, command_string, 1);
if (has_body){
String body_text = substr(l, body_start, body_end - body_start);
body_text = skip_chop_whitespace(body_text);
append(out, "<a href='#");
append(out, body_text);
append(out, "_doc'>");
append(out, body_text);
append(out, "</a>");
}
}break;
case Cmd_BeginList: }break;
{
append(out,"<ul style='margin-top: 5mm; margin-left: 1mm;'>");
}break;
case Cmd_EndList: // TODO(allen): upgrade this bs
{ case Cmd_DocLink:
append(out, "</ul>"); {
}break; String body_text = {0};
b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true);
if (has_body){
append(out, "<a href='#");
append(out, body_text);
append(out, "_doc'>");
append(out, body_text);
append(out, "</a>");
}
}break;
case Cmd_BeginItem: case Cmd_BeginList:
{ {
if (item_counter == 0){ append(out,"<ul style='margin-top: 5mm; margin-left: 1mm;'>");
append(out, "<li style='font-size: 95%; background: #EFEFDF;'>"); }break;
++item_counter;
}
else{
append(out, "<li style='font-size: 95%;'>");
item_counter = 0;
}
}break;
case Cmd_EndItem: case Cmd_EndList:
{ {
append(out, "</li>"); append(out, "</ul>");
}break; }break;
case Cmd_Section: case Cmd_BeginItem:
{ {
// TODO(allen): undo the duplication of this body extraction code. if (item_counter == 0){
i32 body_start = 0, body_end = 0; append(out, "<li style='font-size: 95%; background: #EFEFDF;'>");
i32 has_body = extract_command_body(out, l, &i, &body_start, &body_end, command_string, 1); ++item_counter;
if (has_body){ }
String body_text = substr(l, body_start, body_end - body_start); else{
body_text = skip_chop_whitespace(body_text); append(out, "<li style='font-size: 95%;'>");
item_counter = 0;
}
}break;
html_render_section_header(out, body_text, null_string, section_counter); case Cmd_EndItem:
section_counter->counter[section_counter->nest_level]; {
++section_counter->nest_level; append(out, "</li>");
item_counter = 0; }break;
}
}break;
case Cmd_BeginLink: case Cmd_BeginLink:
{ {
i32 body_start = 0, body_end = 0; String body_text = {0};
i32 has_body = extract_command_body(out, l, &i, &body_start, &body_end, command_string, 1); b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true);
if (has_body){ if (has_body){
String body_text = substr(l, body_start, body_end - body_start); append(out, "<a ");
body_text = skip_chop_whitespace(body_text); if (body_text.str[0] == '!'){
append(out, "target='_blank' ");
append(out, "<a "); body_text.str++;
if (body_text.str[0] == '!'){ body_text.size--;
append(out, "target='_blank' "); }
body_text.str++; append(out, "href='");
body_text.size--; if (match_part_sc(body_text, "document:")){
} String doc_name = substr_tail(body_text, sizeof("document:")-1);
append(out, "href='"); Abstract_Item *doc_lookup = get_item_by_name(doc_system->doc_list, doc_name);
if (match_part_sc(body_text, "document:")){ if (doc_lookup){
String doc_name = substr_tail(body_text, sizeof("document:")-1); char space[256];
Abstract_Item *doc_lookup = get_item_by_name(doc_system->doc_list, doc_name); if (doc_get_link_string(doc_lookup, space, sizeof(space))){
if (doc_lookup){ append(out, space);
char space[256];
if (doc_get_link_string(doc_lookup, space, sizeof(space))){
append(out, space);
}
else{
NotImplemented;
}
}
} }
else{ else{
append(out, body_text); NotImplemented;
}
append(out, "'>");
}
}break;
case Cmd_EndLink:
{
append(out, "</a>");
}break;
case Cmd_Image:
{
// TODO(allen): generalize this
i32 body_start = 0, body_end = 0;
i32 has_body = extract_command_body(out, l, &i, &body_start, &body_end, command_string, 1);
if (has_body){
String body_text = substr(l, body_start, body_end - body_start);
body_text = skip_chop_whitespace(body_text);
i32 pixel_height = 10;
i32 pixel_width = HTML_WIDTH;
body_start = 0, body_end = 0;
has_body = extract_command_body(out, l, &i, &body_start, &body_end, command_string, 0);
if (has_body){
String size_parameter = substr(l, body_start, body_end - body_start);
if (match_part_sc(size_parameter, "width:")){
String width_string = substr_tail(size_parameter, sizeof("width:")-1);
if (str_is_int_s(width_string)){
pixel_width = str_to_int_s(width_string);
}
}
}
if (match_part_sc(body_text, "image:")){
String img_name = substr_tail(body_text, sizeof("image:")-1);
Abstract_Item *img_lookup = get_item_by_name(doc_system->img_list, img_name);
if (img_lookup){
pixel_height = ceil32(pixel_width*img_lookup->h_w_ratio);
append(out, "<img src='");
char space[256];
if (img_get_link_string(img_lookup, space, sizeof(space), pixel_width, pixel_height)){
append(out, space);
add_image_instantiation(&img_lookup->img_instantiations, pixel_width, pixel_height);
}
else{
NotImplemented;
}
append(out, "' style='width: ");
append_int_to_str(out, pixel_width);
append(out, "px; height: ");
append_int_to_str(out, pixel_height);
append(out, "px;'>");
}
} }
} }
}break; }
else{
append(out, body_text);
}
append(out, "'>");
}
}break;
case Cmd_Video: case Cmd_EndLink:
{ {
// TODO(allen): generalize this append(out, "</a>");
i32 body_start = 0, body_end = 0; }break;
i32 has_body = extract_command_body(out, l, &i, &body_start, &body_end, command_string, 1);
case Cmd_Image:
{
String body_text = {0};
b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true);
if (has_body){
i32 pixel_height = 10;
i32 pixel_width = HTML_WIDTH;
String size_parameter = {0};
b32 has_body = extract_command_body(out, l, &i, &size_parameter, command_string, false);
if (has_body){
if (match_part_sc(size_parameter, "width:")){
String width_string = substr_tail(size_parameter, sizeof("width:")-1);
if (str_is_int_s(width_string)){
pixel_width = str_to_int_s(width_string);
}
}
}
if (match_part_sc(body_text, "image:")){
String img_name = substr_tail(body_text, sizeof("image:")-1);
Abstract_Item *img_lookup = get_item_by_name(doc_system->img_list, img_name);
if (img_lookup){
pixel_height = ceil32(pixel_width*img_lookup->h_w_ratio);
append(out, "<img src='");
char space[256];
if (img_get_link_string(img_lookup, space, sizeof(space), pixel_width, pixel_height)){
append(out, space);
add_image_instantiation(&img_lookup->img_instantiations, pixel_width, pixel_height);
}
else{
NotImplemented;
}
append(out, "' style='width: ");
append_int_to_str(out, pixel_width);
append(out, "px; height: ");
append_int_to_str(out, pixel_height);
append(out, "px;'>");
}
}
}
}break;
case Cmd_Video:
{
String body_text = {0};
b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true);
if (has_body){
if (match_part_sc(body_text, "youtube:")){
i32 pixel_width = HTML_WIDTH; i32 pixel_width = HTML_WIDTH;
i32 pixel_height = (i32)(pixel_width * 0.5625); i32 pixel_height = (i32)(pixel_width * 0.5625);
if (has_body){ String youtube_str = substr_tail(body_text, sizeof("youtube:")-1);
String body_text = substr(l, body_start, body_end - body_start);
body_text = skip_chop_whitespace(body_text);
if (match_part_sc(body_text, "youtube:")){ append(out, "<iframe width='");
String youtube_str = substr_tail(body_text, sizeof("youtube:")-1); append_int_to_str(out, pixel_width);
append(out, "' height='");
append(out, "<iframe width='"); append_int_to_str(out, pixel_height);
append_int_to_str(out, pixel_width); append(out, "' src='");
append(out, "' height='"); append(out, youtube_str);
append_int_to_str(out, pixel_height); append(out, "' allowfullscreen> </iframe>");
append(out, "' src='"); }
append(out, youtube_str);
append(out, "' allowfullscreen> </iframe>");
}
}
}break;
case Cmd_EndSection:
{
if (section_counter->nest_level > 0){
--section_counter->nest_level;
++section_counter->counter[section_counter->nest_level];
}
else{
append(out, "<span style='color:#F00'>! Doc generator error: unmatched section end !</span>");
fprintf(stderr, "error: unmatched section end\n");
}
}break;
} }
} }break;
else{
append(out, "<span style='color:#F00'>! Doc generator error: unrecognized command !</span>");
fprintf(stderr, "error: unrecognized command %.*s\n", command_string.size, command_string.str);
}
start = i; case Cmd_Section:
{
String body_text = {0};
b32 has_body = extract_command_body(out, l, &i, &body_text, command_string, true);
if (has_body){
html_render_section_header(out, body_text, null_string, section_counter);
++section_counter->nest_level;
item_counter = 0;
}
}break;
case Cmd_EndSection:
{
if (section_counter->nest_level > 0){
--section_counter->nest_level;
++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");
}
}break;
case Cmd_TableOfContents:
{
fprintf(stdout, "Cmd_TableOfContents: not implemented\n");
}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);
}break;
} }
start = i;
} }
} }
if (start != i){ if (start != i){
append(out, substr(l, start, i-start)); output_plain_old_text(out, l.str + start, i - start);
} }
append(out, "</p>"); append(out, "</p>");
@ -1252,7 +1305,7 @@ internal void
print_function_docs(String *out, String name, String doc_string){ print_function_docs(String *out, String name, String doc_string){
if (doc_string.size == 0){ if (doc_string.size == 0){
append(out, "No documentation generated for this function."); append(out, "No documentation generated for this function.");
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str); fprintf(stdout, "warning: no documentation string for %.*s\n", name.size, name.str);
} }
Temp temp = fm_begin_temp(); Temp temp = fm_begin_temp();
@ -1400,7 +1453,7 @@ print_item_html(String *out, Used_Links *used, Item_Node *item, char *id_postfix
append(out, HTML_DOC_ITEM_CLOSE); append(out, HTML_DOC_ITEM_CLOSE);
} }
else{ else{
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str); fprintf(stdout, "warning: no documentation string for %.*s\n", name.size, name.str);
} }
print_see_also(out, &doc); print_see_also(out, &doc);
@ -1431,7 +1484,7 @@ print_item_html(String *out, Used_Links *used, Item_Node *item, char *id_postfix
append(out, HTML_DOC_ITEM_CLOSE); append(out, HTML_DOC_ITEM_CLOSE);
} }
else{ else{
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str); fprintf(stdout, "warning: no documentation string for %.*s\n", name.size, name.str);
} }
if (item->first_child){ if (item->first_child){
@ -1509,7 +1562,7 @@ print_item_html(String *out, Used_Links *used, Item_Node *item, char *id_postfix
append(out, HTML_DOC_ITEM_CLOSE); append(out, HTML_DOC_ITEM_CLOSE);
} }
else{ else{
fprintf(stderr, "warning: no documentation string for %.*s\n", name.size, name.str); fprintf(stdout, "warning: no documentation string for %.*s\n", name.size, name.str);
} }
if (!hide_members){ if (!hide_members){
@ -1631,7 +1684,9 @@ doc_item_html(String *out, Document_System *doc_system, Used_Links *used_links,
case Doc_Enriched_Text: case Doc_Enriched_Text:
{ {
if (head){ if (head){
write_enriched_text_html(out, item->text.text, doc_system, section_counter); write_enriched_text_html(out, item->enriched_text
.text, doc_system, section_counter);
} }
}break; }break;
@ -1727,6 +1782,11 @@ doc_item_html(String *out, Document_System *doc_system, Used_Links *used_links,
append(out, "</ul>"); append(out, "</ul>");
} }
}break; }break;
case Doc_Plain_Old_Text:
{
output_plain_old_text(out, item->text.text.str, item->text.text.size);
}break;
} }
} }

View File

@ -1,3 +1,4 @@
/* /*
* Mr. 4th Dimention - Allen Webster * Mr. 4th Dimention - Allen Webster
* *
@ -40,7 +41,7 @@
// Meta Parse Rules // Meta Parse Rules
// //
static void internal void
print_function_body_code(String *out, Parse_Context *context, i32 start){ print_function_body_code(String *out, Parse_Context *context, i32 start){
String pstr = {0}, lexeme = {0}; String pstr = {0}, lexeme = {0};
Cpp_Token *token = 0; Cpp_Token *token = 0;
@ -52,7 +53,7 @@ print_function_body_code(String *out, Parse_Context *context, i32 start){
for (; (token = get_token(context)) != 0; get_next_token(context)){ for (; (token = get_token(context)) != 0; get_next_token(context)){
if (do_whitespace_print){ if (do_whitespace_print){
pstr = str_start_end(context->data, start, token->start); pstr = str_start_end(context->data, start, token->start);
append_ss(out, pstr); append(out, pstr);
} }
else{ else{
do_whitespace_print = 1; do_whitespace_print = 1;
@ -77,7 +78,7 @@ print_function_body_code(String *out, Parse_Context *context, i32 start){
if (do_print){ if (do_print){
pstr = get_lexeme(*token, context->data); pstr = get_lexeme(*token, context->data);
append_ss(out, pstr); append(out, pstr);
} }
start = token->start + token->size; start = token->start + token->size;
@ -88,7 +89,7 @@ print_function_body_code(String *out, Parse_Context *context, i32 start){
} }
} }
static void internal void
do_html_output(Document_System *doc_system, char *dst_directory, Abstract_Item *doc){ do_html_output(Document_System *doc_system, char *dst_directory, Abstract_Item *doc){
String out = make_string_cap(fm__push(10 << 20), 0, 10 << 20); String out = make_string_cap(fm__push(10 << 20), 0, 10 << 20);
Assert(out.str != 0); Assert(out.str != 0);
@ -103,7 +104,7 @@ do_html_output(Document_System *doc_system, char *dst_directory, Abstract_Item *
} }
// TODO(allen): replace the documentation declaration system with a straight up enriched text system // TODO(allen): replace the documentation declaration system with a straight up enriched text system
static Abstract_Item* internal Abstract_Item*
generate_4coder_docs(Document_System *doc_system, char *code_directory, char *src_directory){ generate_4coder_docs(Document_System *doc_system, char *code_directory, char *src_directory){
Meta_Unit *custom_types_unit = fm_push_array(Meta_Unit, 1); Meta_Unit *custom_types_unit = fm_push_array(Meta_Unit, 1);
Meta_Unit *lexer_funcs_unit = fm_push_array(Meta_Unit, 1); Meta_Unit *lexer_funcs_unit = fm_push_array(Meta_Unit, 1);
@ -241,7 +242,7 @@ generate_page(Document_System *doc_system, char *code_directory, char *src_direc
return(doc); return(doc);
} }
static String internal String
push_string(i32 size){ push_string(i32 size){
String str = {0}; String str = {0};
str.memory_size = size; str.memory_size = size;
@ -250,24 +251,27 @@ push_string(i32 size){
return(str); return(str);
} }
static void internal void
do_image_resize(char *src_file, char *dst_file, char *extension, i32 w, i32 h){ do_image_resize(char *src_file, char *dst_file, char *extension, i32 w, i32 h){
Temp temp = fm_begin_temp(); Temp temp = fm_begin_temp();
i32 x = 0, y = 0, channels = 0; i32 x = 0, y = 0, channels = 0;
stbi_uc *image = stbi_load(src_file, &x, &y, &channels, 0); stbi_uc *image = stbi_load(src_file, &x, &y, &channels, 0);
stbi_uc *resized_image = fm_push_array(stbi_uc, w*h*channels); if (image != 0){
stbir_resize_uint8(image, x, y, x*channels, resized_image, w, h, w*channels, channels); stbi_uc *resized_image = fm_push_array(stbi_uc, w*h*channels);
stbir_resize_uint8(image, x, y, x*channels, resized_image, w, h, w*channels, channels);
if (match_cc(extension, "png")){ if (match_cc(extension, "png")){
stbi_write_png(dst_file, w, h, channels, resized_image, w*channels); stbi_write_png(dst_file, w, h, channels, resized_image, w*channels);
}
free(image);
} }
free(image);
fm_end_temp(temp); fm_end_temp(temp);
} }
static void internal void
generate_site(char *code_directory, char *asset_directory, char *src_directory, char *dst_directory){ generate_site(char *code_directory, char *asset_directory, char *src_directory, char *dst_directory){
Document_System doc_system = create_document_system(); Document_System doc_system = create_document_system();
@ -284,11 +288,11 @@ generate_site(char *code_directory, char *asset_directory, char *src_directory,
}; };
Site_Asset asset_list[] = { Site_Asset asset_list[] = {
{"4coder_logo_low_green.png", "png", "4coder_logo", SiteAsset_Image}, {"4coder_logo_low_green.png", "png", "4coder_logo", SiteAsset_Image },
{"screen_1.png", "png", "screen_1", SiteAsset_Image}, {"screen_1.png", "png", "screen_1", SiteAsset_Image },
{"screen_2.png", "png", "screen_2", SiteAsset_Image}, {"screen_2.png", "png", "screen_2", SiteAsset_Image },
{"screen_3.png", "png", "screen_3", SiteAsset_Image}, {"screen_3.png", "png", "screen_3", SiteAsset_Image },
{"4coder_icon.ico", "ico", "4coder_icon", SiteAsset_Generic}, {"4coder_icon.ico", "ico", "4coder_icon", SiteAsset_Generic },
}; };
for (u32 i = 0; i < ArrayCount(asset_list); ++i){ for (u32 i = 0; i < ArrayCount(asset_list); ++i){
@ -330,7 +334,7 @@ generate_site(char *code_directory, char *asset_directory, char *src_directory,
node = node->next){ node = node->next){
Abstract_Item *doc = NodeGetData(node, Abstract_Item); Abstract_Item *doc = NodeGetData(node, Abstract_Item);
Assert(doc->item_type == ItemType_Document); Assert(doc->item_type == ItemType_Document);
do_html_output(&doc_system, dst_directory, doc); do_html_output(&doc_system, dst_directory, doc);
} }
for (Basic_Node *node = doc_system.file_list.head; for (Basic_Node *node = doc_system.file_list.head;