From f3899c2f35f2c1b454bf756b15c6415003501e66 Mon Sep 17 00:00:00 2001 From: Matt Mascarenhas Date: Sat, 19 Aug 2017 22:41:51 +0100 Subject: [PATCH] hmml_to_html.c: Add keywords and sort topic dots --- hmml_to_html/hmml_to_html.c | 375 ++++++++++++++++++------------------ 1 file changed, 191 insertions(+), 184 deletions(-) diff --git a/hmml_to_html/hmml_to_html.c b/hmml_to_html/hmml_to_html.c index d1d79b1..9ca83b6 100644 --- a/hmml_to_html/hmml_to_html.c +++ b/hmml_to_html/hmml_to_html.c @@ -27,10 +27,10 @@ typedef unsigned int bool; enum { - EDITION_SINGLE = 0, - EDITION_PROJECT = 1, - EDITION_NETWORK = 2 -} EDITION; + EDITION_SINGLE, + EDITION_PROJECT, + EDITION_NETWORK +}; typedef struct { @@ -72,6 +72,12 @@ typedef struct char WrittenText[32]; } category_info; +typedef struct +{ + category_info Category[64]; + int Count; +} categories; + // TODO(matt): Parse this stuff out of a config file typedef struct { @@ -214,6 +220,7 @@ CopyBuffer(buffer *Dest, buffer *Src) } *Dest->Ptr++ = *Src->Ptr++; } + *Dest->Ptr = '\0'; } __attribute__ ((format (printf, 2, 3))) @@ -472,10 +479,10 @@ SanitisePunctuation(char *String) enum { - CreditsError_NoHost = 1 << 0, - CreditsError_NoAnnotator = 1 << 1, - CreditsError_NoCredentials = 1 << 2 -} CreditsErrorCodes; + CreditsError_NoHost, + CreditsError_NoAnnotator, + CreditsError_NoCredentials +}; int SearchCredentials(buffer *CreditsMenu, bool *HasCreditsMenu, char *ImagesDir, char *Person, char* Role) @@ -730,145 +737,110 @@ BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMM } void -BuildFilter(category_info *TopicsArray, int *UniqueTopics, category_info *MediaArray, int *UniqueMedia, char *Marker) +InsertCategory(categories *Topics, categories *Media, bool *HasTopic, bool *HasMedium, char *Marker) { bool IsMedium = FALSE; - int i = 0; - for(i = 0; i < ArrayCount(CategoryMedium); ++i) + int CategoryMediumIndex; + for(CategoryMediumIndex = 0; CategoryMediumIndex < ArrayCount(CategoryMedium); ++CategoryMediumIndex) { - if(!StringsDiffer(CategoryMedium[i].Medium, Marker)) + if(!StringsDiffer(CategoryMedium[CategoryMediumIndex].Medium, Marker)) { IsMedium = TRUE; + *HasMedium = TRUE; break; } } - int Offset; + int CategoryIndex; if(IsMedium) { - int j = 0; - for(j = 0; j < *UniqueMedia; ++j) + for(CategoryIndex = 0; CategoryIndex < Media->Count; ++CategoryIndex) { - if(!StringsDiffer(CategoryMedium[i].Medium, MediaArray[j].Marker)) + if(!StringsDiffer(CategoryMedium[CategoryMediumIndex].Medium, Media->Category[CategoryIndex].Marker)) { return; } - if((Offset = StringsDiffer(CategoryMedium[i].WrittenName, MediaArray[j].WrittenText)) < 0) + if((StringsDiffer(CategoryMedium[CategoryMediumIndex].WrittenName, Media->Category[CategoryIndex].WrittenText)) < 0) { - int k; - for(k = *UniqueMedia; k > j; --k) + int CategoryCount; + for(CategoryCount = Media->Count; CategoryCount > CategoryIndex; --CategoryCount) { - CopyString(MediaArray[k].Marker, MediaArray[k-1].Marker); - CopyString(MediaArray[k].WrittenText, MediaArray[k-1].WrittenText); + CopyString(Media->Category[CategoryCount].Marker, Media->Category[CategoryCount-1].Marker); + CopyString(Media->Category[CategoryCount].WrittenText, Media->Category[CategoryCount-1].WrittenText); } - CopyString(MediaArray[k].Marker, CategoryMedium[i].Medium); - CopyString(MediaArray[k].WrittenText, CategoryMedium[i].WrittenName); + CopyString(Media->Category[CategoryCount].Marker, CategoryMedium[CategoryMediumIndex].Medium); + CopyString(Media->Category[CategoryCount].WrittenText, CategoryMedium[CategoryMediumIndex].WrittenName); break; } } - if(j == *UniqueMedia) + if(CategoryIndex == Media->Count) { - CopyString(MediaArray[j].Marker, CategoryMedium[i].Medium); - CopyString(MediaArray[j].WrittenText, CategoryMedium[i].WrittenName); + CopyString(Media->Category[CategoryIndex].Marker, CategoryMedium[CategoryMediumIndex].Medium); + CopyString(Media->Category[CategoryIndex].WrittenText, CategoryMedium[CategoryMediumIndex].WrittenName); } - ++*UniqueMedia; - return; + ++Media->Count; } else { - int i = 0; - for(i = 0; i < *UniqueTopics; ++i) + *HasTopic = TRUE; + for(CategoryIndex = 0; CategoryIndex < Topics->Count; ++CategoryIndex) { - if(!StringsDiffer(Marker, TopicsArray[i].Marker)) + if(!StringsDiffer(Marker, Topics->Category[CategoryIndex].Marker)) { return; } - if((Offset = StringsDiffer(Marker, TopicsArray[i].Marker)) < 0) + if((StringsDiffer(Marker, Topics->Category[CategoryIndex].Marker)) < 0) { - int j; - for(j = *UniqueTopics; j > i; --j) + int CategoryCount; + for(CategoryCount = Topics->Count; CategoryCount > CategoryIndex; --CategoryCount) { - CopyString(TopicsArray[j].Marker, TopicsArray[j-1].Marker); + CopyString(Topics->Category[CategoryCount].Marker, Topics->Category[CategoryCount-1].Marker); } - CopyString(TopicsArray[j].Marker, Marker); + CopyString(Topics->Category[CategoryCount].Marker, Marker); break; } } - if(i == *UniqueTopics) + if(CategoryIndex == Topics->Count) { - CopyString(TopicsArray[i].Marker, Marker); + CopyString(Topics->Category[CategoryIndex].Marker, Marker); } - ++*UniqueTopics; - return; + ++Topics->Count; } + + return; } void -BuildCategories(buffer *AnnotationClass, buffer *Category, int *MarkerIndex, bool *HasCategory, bool *HasMedium, char *Marker) +BuildCategories(buffer *AnnotationClass, buffer *TopicDots, categories LocalTopics, categories LocalMedia, int *MarkerIndex) { - // NOTE(matt): This guy could also sort, so that the dots appear in a consistent order in the annotations - // If so, the Category buffer would have to only contain the category names and no more until collation time - // BuildCategories() would have to parse the Category.Location out to an array, sort that array and write it back in - // The code in the "annotation loop" would then have to write both the head and tail of the category stuff - for(int i = 0; i < ArrayCount(CategoryMedium); ++i) + if(LocalTopics.Count > 0) { - if(!StringsDiffer(CategoryMedium[i].Medium, Marker)) + CopyStringToBuffer(TopicDots, ""); + for(int i = 0; i < LocalTopics.Count; ++i) { - CopyStringToBuffer(AnnotationClass, " %s", SanitisePunctuation(Marker)); - *HasMedium = TRUE; - ++*MarkerIndex; - return; + CopyStringToBuffer(TopicDots, "
", + SanitisePunctuation(LocalTopics.Category[i].Marker), + SanitisePunctuation(LocalTopics.Category[i].Marker)); + + CopyStringToBuffer(AnnotationClass, " cat_%s", + SanitisePunctuation(LocalTopics.Category[i].Marker)); } + CopyStringToBuffer(TopicDots, "
"); } - if(*HasCategory == FALSE) + + for(int i = 0; i < LocalMedia.Count; ++i) { - CopyStringToBuffer(Category, ""); - *HasCategory = TRUE; + CopyStringToBuffer(AnnotationClass, " %s", SanitisePunctuation(LocalMedia.Category[i].Marker)); } - // NOTE(matt): Iterate through the Category->Location looking for "Marker", and bail if we find it - char *Ptr = Category->Location; - bool Found = FALSE; - while(*Ptr) - { - if(*Ptr == '\"') - { - ++Ptr; - if(!StringsDifferT(SanitisePunctuation(Marker), Ptr, ' ')) - { - Found = TRUE; - break; - } - else - { - while(*Ptr != '\"') - { - ++Ptr; - } - } - } - ++Ptr; - } - - if(Found == FALSE) - { - CopyStringToBuffer(Category, "
", - SanitisePunctuation(Marker), - SanitisePunctuation(Marker)); - - CopyStringToBuffer(AnnotationClass, " cat_%s", - SanitisePunctuation(Marker)); - } - - ++*MarkerIndex; - return; + CopyStringToBuffer(AnnotationClass, "\""); } int @@ -1448,7 +1420,10 @@ PrintUsage(char *BinaryLocation, char *DefaultCSSDir, char *DefaultImagesDir, ch " \n" " (must come after )\n" " Other available tags include:\n" - " \n", + " \n" + "\n" + "HMML Specification:\n" + " https://git.handmade.network/Annotation-Pushers/Annotation-System/wikis/hmmlspec\n", BinaryLocation, DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultTemplateLocation); } @@ -1814,7 +1789,7 @@ main(int ArgC, char **Args) buffer AnnotationClass; buffer AnnotationData; buffer Text; - buffer Category; + buffer TopicDots; buffer Script; buffer FilterState; @@ -1881,8 +1856,8 @@ main(int ArgC, char **Args) ClaimBuffer(&MemoryArena, &ClaimedMemory, &FilterState, "FilterState", Kilobytes(4)); ref_info ReferencesArray[200] = { 0 }; - category_info TopicsArray[56] = { 0 }; - category_info MediaArray[8] = { 0 }; + categories Topics = { 0 }; + categories Media = { 0 }; bool HasQuoteMenu = FALSE; bool HasReferenceMenu = FALSE; @@ -1892,8 +1867,6 @@ main(int ArgC, char **Args) int QuoteIdentifier = 0x3b1; int RefIdentifier = 1; int UniqueRefs = 0; - int UniqueTopics = 0; - int UniqueMedia = 0; CopyStringToBuffer(&Menus, "
\n" @@ -1935,7 +1908,9 @@ goto Cleanup; printf("%d\n", AnnotationIndex); #endif HMML_Annotation *Anno = HMML.annotations + AnnotationIndex; - bool HasCategory = FALSE; + categories LocalTopics = { 0 }; + bool HasTopic = FALSE; + categories LocalMedia = { 0 }; bool HasMedium = FALSE; bool HasQuote = FALSE; bool HasReference = FALSE; @@ -1947,13 +1922,13 @@ goto Cleanup; // AnnotationClass // AnnotationData // Text - // Category + // TopicDots ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationHeader, "AnnotationHeader", 512); ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationClass, "AnnotationClass", 256); ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationData, "AnnotationData", 512); ClaimBuffer(&MemoryArena, &ClaimedMemory, &Text, "Text", Kilobytes(4)); - ClaimBuffer(&MemoryArena, &ClaimedMemory, &Category, "Category", 512); + ClaimBuffer(&MemoryArena, &ClaimedMemory, &TopicDots, "TopicDots", 512); CopyStringToBuffer(&AnnotationHeader, "
author); @@ -2065,13 +2040,12 @@ goto Cleanup; else if(Anno->markers[MarkerIndex].type == HMML_CATEGORY) { GenerateTopicColours(&Colour, Anno->markers[MarkerIndex].marker, CSSDir); - // TODO(matt): Maybe stuff this into BuildCategories if(!HasFilterMenu) { HasFilterMenu = TRUE; } - BuildFilter(TopicsArray, &UniqueTopics, MediaArray, &UniqueMedia, Anno->markers[MarkerIndex].marker); - BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, &HasMedium, Anno->markers[MarkerIndex].marker); + InsertCategory(&Topics, &Media, &HasTopic, &HasMedium, Anno->markers[MarkerIndex].marker); // Global + InsertCategory(&LocalTopics, &LocalMedia, &HasTopic, &HasMedium, Anno->markers[MarkerIndex].marker); // Local } } @@ -2242,6 +2216,7 @@ goto Cleanup; break; default: *Text.Ptr++ = *InPtr++; + *Text.Ptr = '\0'; break; } } @@ -2327,25 +2302,25 @@ goto Cleanup; while(MarkerIndex < Anno->marker_count) { GenerateTopicColours(&Colour, Anno->markers[MarkerIndex].marker, CSSDir); - // TODO(matt): Maybe stuff this into BuildCategories if(!HasFilterMenu) { HasFilterMenu = TRUE; } if(Anno->markers[MarkerIndex].marker) { - BuildFilter(TopicsArray, &UniqueTopics, MediaArray, &UniqueMedia, Anno->markers[MarkerIndex].marker); + InsertCategory(&Topics, &Media, &HasTopic, &HasMedium, Anno->markers[MarkerIndex].marker); } - BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, &HasMedium, Anno->markers[MarkerIndex].marker); + InsertCategory(&LocalTopics, &LocalMedia, &HasTopic, &HasMedium, Anno->markers[MarkerIndex].marker); + ++MarkerIndex; } if(!HasMedium) { - BuildFilter(TopicsArray, &UniqueTopics, MediaArray, &UniqueMedia, DefaultMedium); - BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, &HasMedium, DefaultMedium); + InsertCategory(&Topics, &Media, &HasTopic, &HasMedium, DefaultMedium); + InsertCategory(&LocalTopics, &LocalMedia, &HasTopic, &HasMedium, DefaultMedium); } - CopyStringToBuffer(&AnnotationClass, "\""); + BuildCategories(&AnnotationClass, &TopicDots, LocalTopics, LocalMedia, &MarkerIndex); CopyBuffer(&AnnotationHeader, &AnnotationClass); if(HasQuote || HasReference) @@ -2360,17 +2335,13 @@ goto Cleanup; "
%s", Anno->time); - - if(HasCategory) - { - CopyStringToBuffer(&Category, ""); - CopyBuffer(&Text, &Category); - } - // NOTE(matt): This feels a bit janky... - *Text.Ptr = '\0'; - CopyBuffer(&Annotation, &Text); + if(HasTopic) + { + CopyBuffer(&Annotation, &TopicDots); + } + CopyStringToBuffer(&Annotation, "
\n" "
\n" "
%s", @@ -2393,13 +2364,13 @@ goto Cleanup; CopyBuffer(&Player, &Annotation); // NOTE(matt): Tree structure of "annotation local" buffer dependencies - // Category + // TopicDots // Text // AnnotationData // AnnotationClass // AnnotationHeader - DeclaimBuffer(&Category, &ClaimedMemory); + DeclaimBuffer(&TopicDots, &ClaimedMemory); DeclaimBuffer(&Text, &ClaimedMemory); DeclaimBuffer(&AnnotationData, &ClaimedMemory); DeclaimBuffer(&AnnotationClass, &ClaimedMemory); @@ -2478,15 +2449,15 @@ goto Cleanup; { CopyStringToBuffer(&FilterState, " var filterState = {\n"); - for(int i = 0; i < UniqueTopics; ++i) + for(int i = 0; i < Topics.Count; ++i) { CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", - TopicsArray[i].Marker, "topic"); + Topics.Category[i].Marker, "topic"); } - for(int i = 0; i < UniqueMedia; ++i) + for(int i = 0; i < Media.Count; ++i) { CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", - MediaArray[i].Marker, "medium"); + Media.Category[i].Marker, "medium"); } CopyStringToBuffer(&FilterState, " };\n"); @@ -2502,7 +2473,7 @@ goto Cleanup; bool HasTopic = FALSE; bool HasMedium = FALSE; - for(int i = 0; i < UniqueTopics; ++i) + for(int i = 0; i < Topics.Count; ++i) { if(!HasTopic) { @@ -2516,12 +2487,12 @@ goto Cleanup; "
\n" " %s\n" "
\n", - TopicsArray[i].Marker, - TopicsArray[i].Marker, - TopicsArray[i].Marker); + Topics.Category[i].Marker, + Topics.Category[i].Marker, + Topics.Category[i].Marker); } - for(int i = 0; i < UniqueMedia; ++i) + for(int i = 0; i < Media.Count; ++i) { if(!HasMedium) { @@ -2535,7 +2506,7 @@ goto Cleanup; int j; for(j = 0; j < ArrayCount(CategoryMedium); ++j) { - if(!StringsDiffer(MediaArray[i].Marker, CategoryMedium[j].Medium)) + if(!StringsDiffer(Media.Category[i].Marker, CategoryMedium[j].Medium)) { break; } @@ -2545,7 +2516,7 @@ goto Cleanup; "
\n" " %s%s\n" "
\n", - MediaArray[i].Marker, + Media.Category[i].Marker, CategoryMedium[j].Icon, CategoryMedium[j].WrittenName ); @@ -2589,104 +2560,107 @@ goto Cleanup; "
\n" " ?

Keyboard Navigation

\n" "\n" - "

Global Keys

\n" - " W, A, P / S, D, N Jump to previous / next marker
\n"); + /* NOTE(matt) */ + "

Global Keys

\n" + " W, A, P / S, D, N Jump to previous / next marker
\n"); if(HasFilterMenu) { CopyStringToBuffer(&Menus, - " z Toggle filter mode V Revert filter to original state\n"); + " z Toggle filter mode V Revert filter to original state\n"); } else { CopyStringToBuffer(&Menus, - " z Toggle filter mode V Revert filter to original state\n"); + " z Toggle filter mode V Revert filter to original state\n"); } CopyStringToBuffer(&Menus, "\n" - "

Menu toggling

\n"); + "

Menu toggling

\n"); if(HasQuoteMenu) { CopyStringToBuffer(&Menus, - " q Quotes\n"); + " q Quotes\n"); } else { CopyStringToBuffer(&Menus, - " q Quotes\n"); + " q Quotes\n"); } if(HasReferenceMenu) { CopyStringToBuffer(&Menus, - " r References\n"); + " r References\n"); } else { CopyStringToBuffer(&Menus, - " r References\n"); + " r References\n"); } if(HasFilterMenu) { CopyStringToBuffer(&Menus, - " f Filter\n"); + " f Filter\n"); } else { CopyStringToBuffer(&Menus, - " f Filter\n"); + " f Filter\n"); } if(HasCreditsMenu) { CopyStringToBuffer(&Menus, - " c Credits\n"); + " c Credits\n"); } else { CopyStringToBuffer(&Menus, - " c Credits\n"); + " c Credits\n"); } CopyStringToBuffer(&Menus, "\n" - "

Movement

\n" - "
\n" - "
\n" - "
\n" - " a\n" + "

Movement

\n" + "
\n" + "
\n" + "
\n" + " a\n" + "
\n" + "
\n" + " w
\n" + " s\n" + "
\n" + "
\n" + " d\n" + "
\n" + "
\n" + "
\n" + " h\n" + " j\n" + " k\n" + " l\n" + "
\n" + "
\n" + "
\n" + " \n" + "
\n" + "
\n" + "
\n" + " \n" + "
\n" + "
\n" + " \n" + "
\n" + "
\n" "
\n" - "
\n" - " w
\n" - " s\n" - "
\n" - "
\n" - " d\n" - "
\n" - "
\n" - "
\n" - " h\n" - " j\n" - " k\n" - " l\n" - "
\n" - "
\n" - "
\n" - " \n" - "
\n" - "
\n" - "
\n" - " \n" - "
\n" - "
\n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n"); + "
\n"); + + // NOTE(matt); if(HasQuoteMenu) { @@ -2726,6 +2700,8 @@ goto Cleanup; " Enter Jump to timecode
\n"); } + CopyStringToBuffer(&Menus, "\n"); + if(HasQuoteMenu) { CopyStringToBuffer(&Menus, @@ -2785,6 +2761,8 @@ goto Cleanup; } } + CopyStringToBuffer(&Menus, "\n"); + if(HasQuoteMenu || HasReferenceMenu || HasCreditsMenu) { CopyStringToBuffer(&Menus, @@ -2816,6 +2794,8 @@ goto Cleanup; " v Invert topics / media as per focus\n"); } + CopyStringToBuffer(&Menus, "\n"); + if(HasCreditsMenu) { CopyStringToBuffer(&Menus, @@ -2841,19 +2821,46 @@ goto Cleanup; // TODO(matt): Maybe do something about indentation levels CopyStringToBuffer(&Includes, - "\n" - "\n" - " \n" - " \n" - " \n" + "\n" " \n" - " ", - JSDir, + " \n" + "\n" + " \n" + " \n", CSSDir, CSSDir, HMML.metadata.project, CSSDir); + if(Topics.Count || Media.Count) + { + CopyStringToBuffer(&Includes, + " 0) + { + for(int i = 0; i < Topics.Count; ++i) + { + CopyStringToBuffer(&Includes, "%s, ", Topics.Category[i].Marker); + } + } + + if(Media.Count > 0) + { + for(int i = 0; i < Media.Count; ++i) + { + CopyStringToBuffer(&Includes, "%s, ", Media.Category[i].WrittenText); + } + } + + Includes.Ptr -= 2; + CopyStringToBuffer(&Includes, "\">\n\n"); + } + + CopyStringToBuffer(&Includes, + " \n", + JSDir); + CopyStringToBuffer(&Script, "