diff --git a/hmml_to_html/hmml_to_html.c b/hmml_to_html/hmml_to_html.c index d250590..4010734 100644 --- a/hmml_to_html/hmml_to_html.c +++ b/hmml_to_html/hmml_to_html.c @@ -5,6 +5,10 @@ ctime -end ${0%.*}.ctm exit #endif +#define DEBUG 1 + +// TODO(matt): Fully investigate the ClaimedMemory situation + typedef unsigned int bool; #define TRUE 1 @@ -19,9 +23,18 @@ typedef struct { char *Location; char *Ptr; + char *ID; int Size; } buffer; +// TODO(matt): Consider putting the ref_info and quote_info into linked lists on the heap, just to avoid all the hardcoded sizes + +typedef struct +{ + char Date[32]; + char Text[512]; +} quote_info; + typedef struct { char Timecode[8]; @@ -42,19 +55,36 @@ typedef struct typedef struct { - char Date[32]; - char Text[512]; -} quote_info; + char Category[32]; + bool IsMedium; +} category_info; #define ArrayCount(A) sizeof(A)/sizeof(*(A)) void -ClaimBuffer(char *MemoryArena, int *ClaimedMemory, buffer *Buffer, int Size) +ClaimBuffer(char *MemoryArena, int *ClaimedMemory, buffer *Buffer, char *ID, int Size) { Buffer->Location = MemoryArena + *ClaimedMemory; Buffer->Size = Size; + Buffer->ID = ID; *ClaimedMemory += Buffer->Size; + *Buffer->Location = '\0'; Buffer->Ptr = Buffer->Location; +#if DEBUG + printf(" Claimed: %s: %d\n" + " Total ClaimedMemory: %d\n\n", Buffer->ID, Buffer->Size, *ClaimedMemory); +#endif +} + +void +DeclaimBuffer(buffer *Buffer, int *ClaimedMemory) +{ + *Buffer->Location = '\0'; + *ClaimedMemory -= Buffer->Size; +#if DEBUG + printf("Declaimed: %s\n" + " Total ClaimedMemory: %d\n\n", Buffer->ID, *ClaimedMemory); +#endif } int @@ -95,6 +125,15 @@ CopyBuffer(buffer *Dest, buffer *Src) Src->Ptr = Src->Location; while(*Src->Ptr) { + // TODO(matt) + { + if(Dest->Ptr - Dest->Location >= Dest->Size) + { + printf("Too big! Too big!\n"); + __asm__("int3"); + + } + } *Dest->Ptr++ = *Src->Ptr++; } } @@ -113,10 +152,28 @@ __attribute__ ((format (printf, 2, 3))) void CopyStringToBuffer(buffer *Dest, char *Format, ...) { + // TODO(matt): + { + if(Dest->Ptr - Dest->Location >= Dest->Size) + { + printf("Too big! Too big!\n"); + __asm__("int3"); + + } + } va_list Args; va_start(Args, Format); int Length = vsprintf(Dest->Ptr, Format, Args); va_end(Args); + // TODO(matt): + { + if(Length + (Dest->Ptr - Dest->Location) >= Dest->Size) + { + printf("Too big! Too big!\n"); + __asm__("int3"); + + } + } Dest->Ptr += Length; } @@ -235,15 +292,6 @@ SanitisePunctuation(char *String) return String; } -char *CategoryMedium[] = -{ - "blackboard", - "owl", - "rant", - "research", - "run", -}; - int BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMML_Reference Ref, HMML_Annotation Anno) { @@ -280,6 +328,7 @@ BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMM CopyString(ReferencesArray[UniqueRefs].ID, Ref.isbn); CopyString(ReferencesArray[UniqueRefs].Source, Ref.author); CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.title); + //TODO(matt): Look into finding the best ISBN searcher the web has to offer CopyString(ReferencesArray[UniqueRefs].URL, "http://www.isbnsearch.org/isbn/%s", Ref.isbn); } else if(Ref.url && Ref.article && Ref.author) @@ -318,12 +367,48 @@ BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMM return 0; } +char *CategoryMedium[][3] = +{ + // category icon written name + { "authored", "🗪", "Chat Comment"}, // TODO(matt): Conditionally handle Chat vs Guest Comments + { "blackboard", "🖌", "Blackboard"}, + { "owl", "🦉", "Owl of Shame"}, + { "default", "🖮", "Programming"}, // TODO(matt): Potentially make this configurable per project + { "rant", "💢", "Rant"}, + { "research", "📖", "Research"}, + { "run", "🏃", "In-Game"} // TODO(matt): Potentially make this configurable per project +}; + +void +BuildFilter(category_info *CategoriesArray, int *UniqueCategories, char *Marker) +{ + int i = 0; + for(i = 0; i < *UniqueCategories; ++i) + { + if(!StringsDiffer(Marker, CategoriesArray[i].Category)) + { + return; + } + } + + ++*UniqueCategories; + CopyString(CategoriesArray[i].Category, Marker); + for(int j = 0; j < ArrayCount(CategoryMedium); ++j) + { + if(!StringsDiffer(CategoryMedium[j][0], Marker)) + { + CategoriesArray[i].IsMedium = TRUE; + } + } + // TODO(matt): Sort the CategoriesArray +} + void BuildCategories(buffer *AnnotationClass, buffer *Category, int *MarkerIndex, bool *HasCategory, char *Marker) { for(int i = 0; i < ArrayCount(CategoryMedium); ++i) { - if(!StringsDiffer(CategoryMedium[i], Marker)) + if(!StringsDiffer(CategoryMedium[i][0], Marker)) { CopyStringToBuffer(AnnotationClass, " %s", SanitisePunctuation(Marker)); ++*MarkerIndex; @@ -360,6 +445,11 @@ StringToInt(char *String) int BuildQuote(quote_info *Info, char *Speaker, int ID) { + // TODO(matt): Pull these paths from the config + // Also notable that there are different paths for different projects + // + // TODO(matt): Handle csv's double quote escaping stuff + char *QuoteDir = "/home/matt/git/GitHub/insofaras/25fc16d58a297a486334"; if(!StringsDiffer(Speaker, "handmade_hero")) { @@ -385,12 +475,14 @@ BuildQuote(quote_info *Info, char *Speaker, int ID) } fread(Buffer, Length, 1, File); fclose(File); + + // TODO(matt): Search the quote store in reverse char *InPtr = Buffer; while(InPtr - Buffer < Length) { - char InID[4] = {0}; + char InID[4] = { 0 }; char *OutPtr = InID; while(*InPtr != ',') { @@ -442,7 +534,7 @@ GenerateTopicColours(buffer *Colour, char *Topic) { for(int i = 0; i < ArrayCount(CategoryMedium); ++i) { - if(!StringsDiffer(Topic, CategoryMedium[i])) + if(!StringsDiffer(Topic, CategoryMedium[i][0])) { return; } @@ -450,6 +542,7 @@ GenerateTopicColours(buffer *Colour, char *Topic) FILE *TopicsFile; char *TopicsBuffer; + // TODO(matt): Consider (optionally) pulling this path from the config if((TopicsFile = fopen("topics.css", "a+"))) { fseek(TopicsFile, 0, SEEK_END); @@ -772,7 +865,7 @@ main(int ArgC, char **Args) // NOTE(matt): Init MemoryArena char *MemoryArena; - int ArenaSize = 1024 * 1024; + int ArenaSize = 1024 * 1024 * 4; if(!(MemoryArena = calloc(ArenaSize, 1))) { perror(Args[0]); @@ -790,6 +883,9 @@ main(int ArgC, char **Args) buffer Title; buffer QuoteMenu; buffer ReferenceMenu; + buffer FilterMenu; + buffer FilterTopics; + buffer FilterMedia; buffer Player; buffer Annotation; @@ -800,6 +896,8 @@ main(int ArgC, char **Args) buffer Category; buffer Colour; + buffer FilterState; + buffer Master; for(int FileIndex = 1; FileIndex < ArgC; ++FileIndex) @@ -816,7 +914,7 @@ main(int ArgC, char **Args) } #if CONFIG - ClaimBuffer(MemoryArena, &ClaimedMemory, &Config, 1024); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Config, "Config", 1024); #endif HMML_Output HMML = hmml_parse_file(InFile); @@ -824,16 +922,28 @@ main(int ArgC, char **Args) if(HMML.well_formed) { - ClaimBuffer(MemoryArena, &ClaimedMemory, &Title, 1024 * 16); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Master, "Master", 1024 * 512); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Player, "Player", 1024 * 256); + + ClaimBuffer(MemoryArena, &ClaimedMemory, &Title, "Title", 1024 * 16); + ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterMenu, "FilterMenu", 1024 * 16); + ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterTopics, "FilterTopics", 1024 * 8); + ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterMedia, "FilterMedia", 1024 * 8); + ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterState, "FilterState", 1024 * 4); + ClaimBuffer(MemoryArena, &ClaimedMemory, &ReferenceMenu, "ReferenceMenu", 1024 * 16); + ClaimBuffer(MemoryArena, &ClaimedMemory, &QuoteMenu, "QuoteMenu", 1024 * 16); + ref_info ReferencesArray[200] = { 0 }; - ClaimBuffer(MemoryArena, &ClaimedMemory, &Player, 1024 * 256); + category_info CategoriesArray[64] = { 0 }; bool HasQuoteMenu = FALSE; bool HasReferenceMenu = FALSE; + bool HasFilterMenu = FALSE; int QuoteIdentifier = 0x3b1; int RefIdentifier = 1; int UniqueRefs = 0; + int UniqueCategories = 0; CopyStringToBuffer(&Title, "
\n" @@ -846,6 +956,9 @@ main(int ArgC, char **Args) for(int AnnotationIndex = 0; AnnotationIndex < HMML.annotation_count; ++AnnotationIndex) { +#if DEBUG + printf("%d\n", AnnotationIndex); +#endif HMML_Annotation *Anno = HMML.annotations + AnnotationIndex; bool HasCategory = FALSE; bool HasQuote = FALSE; @@ -853,11 +966,10 @@ main(int ArgC, char **Args) quote_info QuoteInfo = { 0 }; - ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationHeader, 512); - ClaimBuffer(MemoryArena, &ClaimedMemory, &Category, 256); - ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationClass, 256); - ClaimBuffer(MemoryArena, &ClaimedMemory, &Text, 1024 * 4); - ClaimBuffer(MemoryArena, &ClaimedMemory, &Colour, 32); + ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationHeader, "AnnotationHeader", 512); + ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationClass, "AnnotationClass", 256); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Text, "Text", 1024 * 4); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Colour, "Colour", 32); CopyStringToBuffer(&AnnotationHeader, "
time)); if(Anno->author) { + if(!HasFilterMenu) + { + HasFilterMenu = TRUE; + } + BuildFilter(CategoriesArray, &UniqueCategories, "authored"); CopyStringToBuffer(&AnnotationClass, " authored"); CopyStringToBuffer(&Text, "%s ", @@ -890,6 +1007,7 @@ Anno->author); { CopyStringToBuffer(&Text, // TODO(matt): Hoverbox + // We should get instructions on how to get this info in the config "%.*s", Anno->markers[MarkerIndex].marker, StringToColourHash(&Colour, Anno->markers[MarkerIndex].marker), @@ -901,6 +1019,7 @@ StringLength(Readable), InPtr); { CopyStringToBuffer(&Text, // TODO(matt): Hoverbox + // We should get instructions on how to get this info in the config "%s", Anno->markers[MarkerIndex].marker, StringToColourHash(&Colour, Anno->markers[MarkerIndex].marker), @@ -911,6 +1030,16 @@ Readable); else if(Anno->markers[MarkerIndex].type == HMML_CATEGORY) { GenerateTopicColours(&Colour, Anno->markers[MarkerIndex].marker); + // TODO(matt): Maybe stuff this into BuildCategories + if(!HasFilterMenu) + { + HasFilterMenu = TRUE; + } + BuildFilter(CategoriesArray, &UniqueCategories, Anno->markers[MarkerIndex].marker); + if(!HasCategory) + { + ClaimBuffer(MemoryArena, &ClaimedMemory, &Category, "Category", 256); + } BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, Anno->markers[MarkerIndex].marker); } } @@ -921,8 +1050,6 @@ Readable); HMML_Reference *CurrentRef = Anno->references + RefIndex; if(!HasReferenceMenu) { - ClaimBuffer(MemoryArena, &ClaimedMemory, &ReferenceMenu, 1024 * 16); - CopyStringToBuffer(&ReferenceMenu, "
\n" " References ▼\n" @@ -987,7 +1114,7 @@ Readable); AppendedIdentifier: if(!HasReference) { - ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, 128); + ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, "AnnotationData", 128); if(CurrentRef->isbn) { CopyStringToBuffer(&AnnotationData, " data-ref=\"%s", CurrentRef->isbn); @@ -1041,7 +1168,6 @@ AppendedIdentifier: { if(!HasQuoteMenu) { - ClaimBuffer(MemoryArena, &ClaimedMemory, &QuoteMenu, 1024 * 16); CopyStringToBuffer(&QuoteMenu, "
\n" " Quotes ▼\n" @@ -1053,7 +1179,7 @@ AppendedIdentifier: if(!HasReference) { - ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, 128); + ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, "AnnotationData", 128); CopyStringToBuffer(&AnnotationData, " data-ref=\"&#%d;", QuoteIdentifier); } else @@ -1106,35 +1232,55 @@ Anno->time); while(MarkerIndex < Anno->marker_count) { GenerateTopicColours(&Colour, Anno->markers[MarkerIndex].marker); - ClaimedMemory -= Colour.Size; + // TODO(matt): Maybe stuff this into BuildCategories + if(!HasFilterMenu) + { + HasFilterMenu = TRUE; + } + if(Anno->markers[MarkerIndex].marker) + { + BuildFilter(CategoriesArray, &UniqueCategories, Anno->markers[MarkerIndex].marker); + } + if(!HasCategory) + { + ClaimBuffer(MemoryArena, &ClaimedMemory, &Category, "Category", 256); + } BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, Anno->markers[MarkerIndex].marker); } CopyStringToBuffer(&AnnotationClass, "\""); CopyBuffer(&AnnotationHeader, &AnnotationClass); - ClaimedMemory -= AnnotationClass.Size; if(HasQuote || HasReference) { CopyStringToBuffer(&AnnotationData, "\""); CopyBuffer(&AnnotationHeader, &AnnotationData); - ClaimedMemory -= AnnotationData.Size; + DeclaimBuffer(&AnnotationData, &ClaimedMemory); } CopyStringToBuffer(&AnnotationHeader, ">\n"); - ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, 1024 * 4); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, "Annotation", 1024 * 8); CopyBuffer(&Annotation, &AnnotationHeader); - ClaimedMemory -= AnnotationHeader.Size; CopyStringToBuffer(&Annotation, "
%s", Anno->time); +#if 0 + // TODO(matt): Handle special-cases, i.e. default media, and possibly other things + if(!HasCategory) + { + ClaimBuffer(MemoryArena, &ClaimedMemory, &Category, "Category", 256); + BuildFilter(CategoriesArray, &UniqueCategories, "default"); + BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, "default"); + } +#endif + if(HasCategory) { CopyStringToBuffer(&Category, ""); CopyBuffer(&Text, &Category); - ClaimedMemory -= Category.Size; + DeclaimBuffer(&Category, &ClaimedMemory); } *Text.Ptr = '\0'; @@ -1155,7 +1301,6 @@ Anno->time); Anno->time); CopyBuffer(&Annotation, &Text); - ClaimedMemory -= Text.Size; CopyStringToBuffer(&Annotation, "
\n" "
\n" @@ -1163,16 +1308,22 @@ Anno->time); CopyBuffer(&Player, &Annotation); - ClaimedMemory -= Annotation.Size; + DeclaimBuffer(&Annotation, &ClaimedMemory); + DeclaimBuffer(&Colour, &ClaimedMemory); + DeclaimBuffer(&Text, &ClaimedMemory); + DeclaimBuffer(&AnnotationClass, &ClaimedMemory); + DeclaimBuffer(&AnnotationHeader, &ClaimedMemory); } +#if DEBUG + printf("EOA\n\n"); +#endif if(HasQuoteMenu) { CopyStringToBuffer(&QuoteMenu, "
\n" "
\n"); CopyBuffer(&Title, &QuoteMenu); - ClaimedMemory -= QuoteMenu.Size; } if(HasReferenceMenu) @@ -1226,9 +1377,108 @@ ReferencesArray[i].Identifier[j].Timecode); "
\n" " \n"); CopyBuffer(&Title, &ReferenceMenu); - ClaimedMemory -= ReferenceMenu.Size; } + if(HasFilterMenu) + { + CopyStringToBuffer(&FilterState, "var filterState = {\n"); + for(int i = 0; i < UniqueCategories; ++i) + { + CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", + CategoriesArray[i].Category, CategoriesArray[i].IsMedium ? "medium" : "topic"); + } + CopyStringToBuffer(&FilterState, "};\n" + "\n"); + + CopyStringToBuffer(&FilterMenu, +"
\n" +" \n" +"
\n" +"
Filter mode:
\n" +"
\n"); + + { + bool HasTopic = FALSE; + bool HasMedium = FALSE; + + for(int i = 0; i < UniqueCategories; ++i) + { + if(CategoriesArray[i].IsMedium) + { + if(!HasMedium) + { + CopyStringToBuffer(&FilterMedia, +"
\n" +"
Media
\n"); + + HasMedium = TRUE; + } + + int j; + for(j = 0; j < ArrayCount(CategoryMedium); ++j) + { + if(!StringsDiffer(CategoriesArray[i].Category, CategoryMedium[j][0])) + { + break; + } + } + + CopyStringToBuffer(&FilterMedia, +"
\n" +" %s%s\n" +"
\n", +CategoriesArray[i].Category, +CategoryMedium[j][1], +CategoryMedium[j][2] +); + + /* +
+ */ + } + else + { + if(!HasTopic) + { + CopyStringToBuffer(&FilterMenu, +"
\n" +"
Topics
\n"); + + HasTopic = TRUE; + } + CopyStringToBuffer(&FilterTopics, +"
\n" +" %s\n" +"
\n", +CategoriesArray[i].Category, +CategoriesArray[i].Category, +CategoriesArray[i].Category); + } + } + + if(HasTopic) + { + CopyStringToBuffer(&FilterTopics, +"
\n"); + CopyBuffer(&FilterMenu, &FilterTopics); + } + if(HasMedium) + { + CopyStringToBuffer(&FilterMedia, +"
\n"); + CopyBuffer(&FilterMenu, &FilterMedia); + } + } + + + CopyStringToBuffer(&FilterMenu, +"
\n" +"
\n" +" \n"); + } + + CopyBuffer(&Title, &FilterMenu); + #if CONFIG // TODO(matt): Here is where I test ParseConfig ParseConfig(&Config, HMML.metadata.annotator); @@ -1243,8 +1493,10 @@ HMML.metadata.annotator); " \n"); //NOTE(matt): Collate the buffers! +#if DEBUG + printf("Buffer Collation\n\n"); +#endif - ClaimBuffer(MemoryArena, &ClaimedMemory, &Master, 1024 * 512); CopyStringToBuffer(&Master, "\n" " \n" @@ -1260,9 +1512,7 @@ HMML.metadata.annotator); //NOTE(matt): Here is where we do all our CopyBuffer() calls CopyBuffer(&Master, &Title); - ClaimedMemory -= Title.Size; CopyBuffer(&Master, &Player); - ClaimedMemory -= Player.Size; // CopyStringToBuffer(&Master, @@ -1299,6 +1549,292 @@ HMML.metadata.annotator); " });\n" "}\n" "\n" +"var filter = document.querySelector(\".filter\");\n" +"var filterModeElement = filter.querySelector(\".filter_mode\");\n" +"var filterMode = filterModeElement.classList[1];\n"); + + if(HasFilterMenu) + { + CopyBuffer(&Master, &FilterState); + } + + DeclaimBuffer(&QuoteMenu, &ClaimedMemory); + DeclaimBuffer(&ReferenceMenu, &ClaimedMemory); + DeclaimBuffer(&FilterState, &ClaimedMemory); + DeclaimBuffer(&FilterMedia, &ClaimedMemory); + DeclaimBuffer(&FilterTopics, &ClaimedMemory); + DeclaimBuffer(&FilterMenu, &ClaimedMemory); + DeclaimBuffer(&Title, &ClaimedMemory); + DeclaimBuffer(&Player, &ClaimedMemory); + + CopyStringToBuffer(&Master, +"// Filter Mode Toggle\n" +"var testMarkers = document.querySelectorAll(\".marker\");\n" +"filterModeElement.addEventListener(\"click\", function(ev) {\n" +" if(filterMode == \"inclusive\")\n" +" {\n" +" filterModeElement.classList.remove(\"inclusive\");\n" +" filterModeElement.classList.add(\"exclusive\");\n" +" filterMode = \"exclusive\";\n" +"\n" +" for(var i = 0; i < testMarkers.length; ++i)\n" +" {\n" +" var testCategories = testMarkers[i].classList;\n" +" for(var j = 0; j < testCategories.length; ++j)\n" +" {\n" +" if((testCategories[j].startsWith(\"off_\")) && !testMarkers[i].classList.contains(\"skip\"))\n" +" {\n" +" testMarkers[i].classList.add(\"skip\");\n" +" }\n" +" }\n" +" }\n" +" }\n" +" else\n" +" {\n" +" filterModeElement.classList.remove(\"exclusive\");\n" +" filterModeElement.classList.add(\"inclusive\");\n" +" filterMode = \"inclusive\";\n" +"\n" +" for(var i = 0; i < testMarkers.length; ++i)\n" +" {\n" +" var testCategories = testMarkers[i].classList;\n" +" for(var j = 0; j < testCategories.length; ++j)\n" +" {\n" +" if((testCategories[j] in filterState || testCategories[j].startsWith(\"cat_\")) && testMarkers[i].classList.contains(\"skip\"))\n" +" {\n" +" testMarkers[i].classList.remove(\"skip\");\n" +" }\n" +" }\n" +" }\n" +" }\n" +"});\n" +"\n" +"// Filter Toggle\n" +"var filterCategories = filter.querySelectorAll(\".filter_topics .filter_content,.filter_media .filter_content\");\n" +"for(var i = 0; i < filterCategories.length; ++i)\n" +"{\n" +" filterCategories[i].addEventListener(\"click\", function(ev) {\n" +" var selectedCategory = this.classList[1];\n" +" filterState[selectedCategory].off = !filterState[selectedCategory].off;\n" +"\n" +" if(filterState[selectedCategory].off)\n" +" {\n" +" this.classList.add(\"off\");\n" +" var testMarkers = document.querySelectorAll(\".marker.\" + selectedCategory + \", .marker.cat_\" + selectedCategory);\n" +" for(var j = 0; j < testMarkers.length; ++j)\n" +" {\n" +" if(filterState[selectedCategory].type == \"topic\")\n" +" {\n" +" testMarkers[j].classList.remove(\"cat_\" + selectedCategory);\n" +" testMarkers[j].classList.add(\"off_\" + selectedCategory);\n" +" var markerCategories = testMarkers[j].querySelectorAll(\".category.\" + selectedCategory);\n" +" for(var k = 0; k < markerCategories.length; ++k)\n" +" {\n" +" if(markerCategories[k].classList.contains(selectedCategory))\n" +" {\n" +" markerCategories[k].classList.add(\"off\");\n" +" }\n" +" }\n" +" }\n" +" else\n" +" {\n" +" testMarkers[j].classList.remove(selectedCategory);\n" +" testMarkers[j].classList.add(\"off_\" + selectedCategory);\n" +" }\n" +"\n" +" Skipping = 1;\n" +" if(filterMode == \"exclusive\")\n" +" {\n" +" testMarkers[j].classList.add(\"skip\");\n" +" }\n" +" else\n" +" {\n" +" var markerClasses = testMarkers[j].classList;\n" +" for(var k = 0; k < markerClasses.length; ++k)\n" +" {\n" +" if(markerClasses[k] in filterState || markerClasses[k].replace(/^cat_/, \"\") in filterState)\n" +" {\n" +" Skipping = 0;\n" +" }\n" +" }\n" +" if(Skipping)\n" +" {\n" +" testMarkers[j].classList.add(\"skip\");\n" +" }\n" +" }\n" +"\n" +" }\n" +" }\n" +" else\n" +" {\n" +" this.classList.remove(\"off\");\n" +" var testMarkers = document.querySelectorAll(\".marker.off_\" + selectedCategory);\n" +" for(var j = 0; j < testMarkers.length; ++j)\n" +" {\n" +" if(filterState[selectedCategory].type == \"topic\")\n" +" {\n" +" testMarkers[j].classList.remove(\"off_\" + selectedCategory);\n" +" testMarkers[j].classList.add(\"cat_\" + selectedCategory);\n" +" var markerCategories = testMarkers[j].querySelectorAll(\".category.\" + selectedCategory);\n" +" for(var k = 0; k < markerCategories.length; ++k)\n" +" {\n" +" if(markerCategories[k].classList.contains(selectedCategory))\n" +" {\n" +" markerCategories[k].classList.remove(\"off\");\n" +" }\n" +" }\n" +" }\n" +" else\n" +" {\n" +" testMarkers[j].classList.remove(\"off_\" + selectedCategory);\n" +" testMarkers[j].classList.add(selectedCategory);\n" +" }\n" +"\n" +" Skipping = 0;\n" +" if(filterMode == \"inclusive\")\n" +" {\n" +" testMarkers[j].classList.remove(\"skip\");\n" +" }\n" +" else\n" +" {\n" +" var markerClasses = testMarkers[j].classList;\n" +" for(var k = 0; k < markerClasses.length; ++k)\n" +" {\n" +" if(markerClasses[k].startsWith(\"off_\"))\n" +" {\n" +" Skipping = 1;\n" +" }\n" +" }\n" +" if(!Skipping)\n" +" {\n" +" testMarkers[j].classList.remove(\"skip\");\n" +" }\n" +" }\n" +" }\n" +" }\n" +" });\n" +"}\n" +"\n" +"var refSources = document.querySelectorAll(\".refs .ref\");\n" +"for (var i = 0; i < refSources.length; ++i) {\n" +" refSources[i].addEventListener(\"click\", function(ev) {\n" +" if (player) {\n" +" player.pause();\n" +" }\n" +" });\n" +"}\n" +"\n" +"function resetFade()\n" +"{\n" +" filter.classList.remove(\"responsible\");\n" +" filter.querySelector(\".filter_mode\").classList.remove(\"responsible\");\n" +" var responsibleCategories = filter.querySelectorAll(\".filter_content.responsible\");\n" +" for(var i = 0; i < responsibleCategories.length; ++i)\n" +" {\n" +" responsibleCategories[i].classList.remove(\"responsible\");\n" +" }\n" +"}\n" +"\n" +"var sourceMenus = document.querySelectorAll(\".menu\");\n" +"function onRefChanged(ref, element) {\n" +" if(element.classList.contains(\"skip\"))\n" +" {\n" +" if(!filter.classList.contains(\"responsible\"))\n" +" {\n" +" filter.classList.add(\"responsible\");\n" +" }\n" +"\n" +" for(var selector = 0; selector < element.classList.length; ++selector)\n" +" {\n" +" if(element.classList[selector].startsWith(\"off_\"))\n" +" {\n" +" if(!filter.querySelector(\".filter_content.\" + element.classList[selector].replace(/^off_/, \"\")).classList.contains(\"responsible\"))\n" +" {\n" +" filter.querySelector(\".filter_content.\" + element.classList[selector].replace(/^off_/, \"\")).classList.add(\"responsible\");\n" +" }\n" +" }\n" +" if((element.classList[selector].startsWith(\"cat_\") || element.classList[selector] in filterState))\n" +" {\n" +" if(!filter.querySelector(\".filter_mode\").classList.add(\"responsible\"))\n" +" {\n" +" filter.querySelector(\".filter_mode\").classList.add(\"responsible\");\n" +" }\n" +" }\n" +" setTimeout(resetFade, 8000);\n" +" }\n" +" player.jumpToNextMarker();\n" +" return;\n" +" }\n" +"\n" +" for (var MenuIndex = 0; MenuIndex < sourceMenus.length; ++MenuIndex)\n" +" {\n" +" var SetMenu = 0;\n" +" if (ref !== undefined && ref !== null) {\n" +" var refElements = sourceMenus[MenuIndex].querySelectorAll(\".refs .ref\");\n" +" var refs = ref.split(\",\");\n" +"\n" +" for (var i = 0; i < refElements.length; ++i) {\n" +" if (refs.includes(refElements[i].getAttribute(\"data-id\"))) {\n" +" refElements[i].classList.add(\"current\");\n" +" SetMenu = 1;\n" +" } else {\n" +" refElements[i].classList.remove(\"current\");\n" +" }\n" +" }\n" +" if(SetMenu) {\n" +" sourceMenus[MenuIndex].classList.add(\"current\");\n" +" } else {\n" +" sourceMenus[MenuIndex].classList.remove(\"current\");\n" +" }\n" +"\n" +" } else {\n" +" sourceMenus[MenuIndex].classList.remove(\"current\");\n" +" var refs = sourceMenus[MenuIndex].querySelectorAll(\".refs .ref\");\n" +" for (var i = 0; i < refs.length; ++i) {\n" +" refs[i].classList.remove(\"current\");\n" +" }\n" +" }\n" +" }\n" +"}\n" +" \n" +" \n" +"\n"); + +#if 0 + CopyStringToBuffer(&Master, +" \n" " \n" "\n"); +#endif FILE *OutFile; if(!(OutFile = fopen("out.html", "w"))) @@ -1355,7 +1892,7 @@ HMML.metadata.annotator); fwrite(Master.Location, Master.Ptr - Master.Location, 1, OutFile); fclose(OutFile); - ClaimedMemory -= Master.Size; + DeclaimBuffer(&Master, &ClaimedMemory); } else { diff --git a/hmml_to_html/riscy.css b/hmml_to_html/riscy.css index 937891d..d6eaf45 100644 --- a/hmml_to_html/riscy.css +++ b/hmml_to_html/riscy.css @@ -1,8 +1,8 @@ .title.riscy, .title.riscy > .menu .refs, -.title.riscy > .menu .filter, +.title.riscy > .menu .filter_container, .title.riscy > .menu > .refs .ref, -.title.riscy > .menu > .filter .filter_mode, +.title.riscy > .menu > .filter_container .filter_mode, .markers_container.riscy, .markers_container.riscy > .marker { background-color: #EEE; @@ -23,8 +23,8 @@ .title.riscy > .menu:hover, .title.riscy > .menu > .refs .ref:hover, -.title.riscy > .menu > .filter .filter_mode:hover, -.title.riscy > .menu > .filter .filter_content:hover, +.title.riscy > .menu > .filter_container .filter_mode:hover, +.title.riscy > .menu > .filter_container .filter_content:hover, .markers_container.riscy > .marker:hover > .content { background-color: #FFF8E7; } @@ -46,7 +46,7 @@ .title.riscy > .menu > .refs .ref .source, .title.riscy > .menu > .refs .ref .quote_byline, -.title > .menu > .filter .filter_content.off .text { +.title > .menu > .filter_container .filter_content.off .text { color: #888; } @@ -96,7 +96,11 @@ * .markers_container.riscy > marker.run */ -/* TODO(matt): Actually style this */ +@keyframes riscy_fade_mode { + 0% { color: #FFF; } + 100% { color: #000; } +} + @keyframes riscy_fade_text { 0% { color: #FFF; } 100% { color: #888; } @@ -107,12 +111,18 @@ 100% { background-color: #EEE; } } +/* TODO(matt): Get this to work! */ +.title.riscy > .menu > .filter_container .filter_mode.responsible { + animation-name: riscy_fade_mode; +} + .title.riscy .filter_content.responsible .text { animation-name: riscy_fade_text; } .title.riscy > .menu.filter.responsible, .title.riscy .filter_content.responsible, -.title.riscy > .menu > .filter .filter_mode.responsible { +.title.riscy > .menu > .filter_container .filter_mode.responsible { animation-name: riscy_fade_background; } + diff --git a/hmml_to_html/style.css b/hmml_to_html/style.css index 2c67ec1..d7fdf68 100644 --- a/hmml_to_html/style.css +++ b/hmml_to_html/style.css @@ -29,14 +29,14 @@ .title > .menu.filter.responsible, .title .filter_content.responsible, .title .filter_content.responsible .text, -.title > .menu > .filter .filter_mode.responsible { +.title > .menu > .filter_container .filter_mode.responsible { animation-duration: 8s; animation-timing-function: ease-out; animation-iteration-count: 1; } .title > .menu .refs, -.title > .menu .filter { +.title > .menu .filter_container { border: 1px solid; border-top: none; display: none; @@ -51,12 +51,12 @@ } .title > .menu:hover .refs, -.title > .menu:hover .filter { +.title > .menu:hover .filter_container { display: block; } .title > .menu > .refs .ref, -.title > .menu > .refs .filter { /* TODO(matt): See what this is! */ +.title > .menu > .refs .filter_container { /* TODO(matt): See what this is! */ border-bottom: 1px solid; padding: 10px; display: flex; @@ -66,7 +66,7 @@ } .title > .menu > .refs .ref:last-child, -.title > .menu > .refs .filter:last-child { /* TODO(matt): See what this is! */ +.title > .menu > .refs .filter_container:last-child { /* TODO(matt): See what this is! */ border: none; } @@ -82,7 +82,7 @@ } .title > .menu > .refs .ref .ref_content, -.title > .menu > .refs .ref .filter_content { +.title > .menu > .filter_content { margin-bottom: 8px; width: 100%; } @@ -120,60 +120,60 @@ margin-right: 4px; } -.title > .menu > .filter .filter_mode { +.title > .menu > .filter_container .filter_mode { cursor: pointer; border-bottom: 1px solid; text-align: center; font-size: 12px; } -.title > .menu > .filter .filter_mode.exclusive:after { +.title > .menu > .filter_container .filter_mode.exclusive:after { content: "exclusive"; } -.title > .menu > .filter .filter_mode.inclusive:after { +.title > .menu > .filter_container .filter_mode.inclusive:after { content: "inclusive"; } -.title > .menu > .filter .filter_title { +.title > .menu > .filter_container .filter_title { font-size: 9px; text-align: center; } -.title > .menu > .filter .filters { +.title > .menu > .filter_container .filters { display: flex; flex-flow: row nowrap; } -.title > .menu > .filter .filters > * { +.title > .menu > .filter_container .filters > * { width: 50%; } -.title > .menu > .filter .filter_content { +.title > .menu > .filter_container .filter_content { cursor: pointer; } -.title > .menu > .filter .filter_content .icon { +.title > .menu > .filter_container .filter_content .icon { margin: 0 4px; } -.title > .menu > .filter > .filter_media .filter_content .icon { +.title > .menu > .filter_container > .filter_media .filter_content .icon { margin: 0 .5em 0 4px; } -.title > .menu > .filter .filter_content.off .icon { +.title > .menu > .filter_container .filter_content.off .icon { background: transparent; } -.title > .menu > .filter .filter_content.rant .icon { +.title > .menu > .filter_container .filter_content.rant .icon { color: #F00; } -.title > .menu > .filter .filter_media .filter_content.off .icon { +.title > .menu > .filter_container .filter_media .filter_content.off .icon { opacity: 0.32; } -.title > .menu > .filter .filter_content.rant .text, +.title > .menu > .filter_container .filter_content.rant .text, .markers_container > .marker.rant .content { font-variant: small-caps; } @@ -254,18 +254,18 @@ margin: 4px; } -.title > .menu > .filter .filter_content { +.title > .menu > .filter_container .filter_content { display: flex; } -.title > .menu > .filter .filter_content .category, +.title > .menu > .filter_container .filter_content .category, .markers_container > .marker .content .categories .category { border-radius: 50%; height: 5px; width: 5px; } -.title > .menu > .filter .filter_content .category.off, +.title > .menu > .filter_container .filter_content .category.off, .markers_container > .marker .content .categories .category.off { background: transparent; } @@ -274,7 +274,7 @@ margin-left: 2px; } -.title > .menu > .filter .filter_content .icon { +.title > .menu > .filter_container .filter_content .icon { margin-right: 8px; }