From 2d9af4ee935fc9de39db0b599bc61d9406b526e6 Mon Sep 17 00:00:00 2001 From: Matt Mascarenhas Date: Wed, 24 May 2017 22:56:36 +0100 Subject: [PATCH] hmml_to_html.c: Sort the filter media [#21] --- hmml_to_html/hmml_to_html.c | 264 +++++++++++++++++++++--------------- 1 file changed, 154 insertions(+), 110 deletions(-) diff --git a/hmml_to_html/hmml_to_html.c b/hmml_to_html/hmml_to_html.c index 9374f72..417afdf 100644 --- a/hmml_to_html/hmml_to_html.c +++ b/hmml_to_html/hmml_to_html.c @@ -17,6 +17,9 @@ typedef unsigned int bool; #include // NOTE(matt): calloc, malloc, free #include "hmmlib.h" +#define Kilobytes(Bytes) Bytes << 10 +#define Megabytes(Bytes) Bytes << 20 + typedef struct { char *Location; @@ -53,8 +56,8 @@ typedef struct typedef struct { - char Category[32]; - bool IsMedium; + char Marker[32]; + char WrittenText[32]; } category_info; #define ArrayCount(A) sizeof(A)/sizeof(*(A)) @@ -127,7 +130,7 @@ CopyBuffer(buffer *Dest, buffer *Src) { if(Dest->Ptr - Dest->Location >= Dest->Size) { - printf("Too big! Too big!\n"); + fprintf(stderr, "CopyBuffer: %s cannot accommodate %s\n", Dest->ID, Src->ID); __asm__("int3"); } @@ -150,14 +153,6 @@ __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); @@ -166,7 +161,7 @@ CopyStringToBuffer(buffer *Dest, char *Format, ...) { if(Length + (Dest->Ptr - Dest->Location) >= Dest->Size) { - printf("Too big! Too big!\n"); + fprintf(stderr, "CopyStringToBuffer: %s cannot accommodate %d-character string\n", Dest->ID, Length); __asm__("int3"); } } @@ -378,46 +373,84 @@ char *CategoryMedium[][3] = }; void -BuildFilter(category_info *CategoriesArray, int *UniqueCategories, char *Marker) +BuildFilter(category_info *TopicsArray, int *UniqueTopics, category_info *MediaArray, int *UniqueMedia, char *Marker) { - int Offset = 0; - int i = 0; - for(i = 0; i < *UniqueCategories; ++i) - { - if(!StringsDiffer(Marker, CategoriesArray[i].Category)) - { - return; - } - if((Offset = StringsDiffer(Marker, CategoriesArray[i].Category)) < 0) - { - int j; - for(j = *UniqueCategories; j > i; --j) - { - CopyString(CategoriesArray[j].Category, CategoriesArray[j-1].Category); - CategoriesArray[j].IsMedium = CategoriesArray[j-1].IsMedium; - } + int Offset; + bool IsMedium = FALSE; - CopyString(CategoriesArray[j].Category, Marker); - CategoriesArray[j].IsMedium = FALSE; + int i = 0; + for(i = 0; i < ArrayCount(CategoryMedium); ++i) + { + if(!StringsDiffer(CategoryMedium[i][0], Marker)) + { + IsMedium = TRUE; break; } } - // This really ought to sort by the Alternative Text - - if(i == *UniqueCategories) + if(IsMedium) { - CopyString(CategoriesArray[i].Category, Marker); - } - - ++*UniqueCategories; - - for(int k = 0; k < ArrayCount(CategoryMedium); ++k) - { - if(!StringsDiffer(CategoryMedium[k][0], Marker)) + int j = 0; + for(j = 0; j < *UniqueMedia; ++j) { - CategoriesArray[i].IsMedium = TRUE; + if(!StringsDiffer(CategoryMedium[i][0], MediaArray[j].Marker)) + { + return; + } + if((Offset = StringsDiffer(CategoryMedium[i][2], MediaArray[j].WrittenText)) < 0) + { + int k; + for(k = *UniqueMedia; k > j; --k) + { + CopyString(MediaArray[k].Marker, MediaArray[k-1].Marker); + CopyString(MediaArray[k].WrittenText, MediaArray[k-1].WrittenText); + } + + CopyString(MediaArray[k].Marker, CategoryMedium[i][0]); + CopyString(MediaArray[k].WrittenText, CategoryMedium[i][2]); + break; + } } + + if(j == *UniqueMedia) + { + CopyString(MediaArray[j].Marker, CategoryMedium[i][0]); + CopyString(MediaArray[j].WrittenText, CategoryMedium[i][2]); + } + + ++*UniqueMedia; + return; + } + else + { + int i = 0; + for(i = 0; i < *UniqueTopics; ++i) + { + if(!StringsDiffer(Marker, TopicsArray[i].Marker)) + { + return; + } + if((Offset = StringsDiffer(Marker, TopicsArray[i].Marker)) < 0) + { + int j; + for(j = *UniqueTopics; j > i; --j) + { + CopyString(TopicsArray[j].Marker, TopicsArray[j-1].Marker); + } + + CopyString(TopicsArray[j].Marker, Marker); + break; + } + } + + // This really ought to sort by the Alternative Text + + if(i == *UniqueTopics) + { + CopyString(TopicsArray[i].Marker, Marker); + } + + ++*UniqueTopics; } } @@ -889,7 +922,7 @@ main(int ArgC, char **Args) // NOTE(matt): Init MemoryArena char *MemoryArena; - int ArenaSize = 1024 * 1024 * 4; + int ArenaSize = Megabytes(4); if(!(MemoryArena = calloc(ArenaSize, 1))) { perror(Args[0]); @@ -953,7 +986,7 @@ main(int ArgC, char **Args) } #if CONFIG - ClaimBuffer(MemoryArena, &ClaimedMemory, &Config, "Config", 1024); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Config, "Config", Kilobytes(1)); #endif HMML_Output HMML = hmml_parse_file(InFile); @@ -974,23 +1007,24 @@ main(int ArgC, char **Args) // Annotation // FilterState - ClaimBuffer(MemoryArena, &ClaimedMemory, &Master, "Master", 1024 * 512); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Master, "Master", Kilobytes(512)); - ClaimBuffer(MemoryArena, &ClaimedMemory, &Title, "Title", 1024 * 16); - ClaimBuffer(MemoryArena, &ClaimedMemory, &QuoteMenu, "QuoteMenu", 1024 * 16); - ClaimBuffer(MemoryArena, &ClaimedMemory, &ReferenceMenu, "ReferenceMenu", 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, &Title, "Title", Kilobytes(16)); + ClaimBuffer(MemoryArena, &ClaimedMemory, &QuoteMenu, "QuoteMenu", Kilobytes(16)); + ClaimBuffer(MemoryArena, &ClaimedMemory, &ReferenceMenu, "ReferenceMenu", Kilobytes(16)); + ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterMenu, "FilterMenu", Kilobytes(16)); + ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterTopics, "FilterTopics", Kilobytes(8)); + ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterMedia, "FilterMedia", Kilobytes(8)); - ClaimBuffer(MemoryArena, &ClaimedMemory, &Player, "Player", 1024 * 256); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Player, "Player", Kilobytes(256)); ClaimBuffer(MemoryArena, &ClaimedMemory, &Colour, "Colour", 32); - ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, "Annotation", 1024 * 8); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, "Annotation", Kilobytes(8)); - ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterState, "FilterState", 1024 * 4); + ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterState, "FilterState", Kilobytes(4)); ref_info ReferencesArray[200] = { 0 }; - category_info CategoriesArray[64] = { 0 }; + category_info TopicsArray[56] = { 0 }; + category_info MediaArray[8] = { 0 }; bool HasQuoteMenu = FALSE; bool HasReferenceMenu = FALSE; @@ -999,7 +1033,8 @@ main(int ArgC, char **Args) int QuoteIdentifier = 0x3b1; int RefIdentifier = 1; int UniqueRefs = 0; - int UniqueCategories = 0; + int UniqueTopics = 0; + int UniqueMedia = 0; CopyStringToBuffer(&Title, "
\n" @@ -1036,8 +1071,8 @@ main(int ArgC, char **Args) ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationHeader, "AnnotationHeader", 512); ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationClass, "AnnotationClass", 256); - ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, "AnnotationData", 128); - ClaimBuffer(MemoryArena, &ClaimedMemory, &Text, "Text", 1024 * 4); + ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, "AnnotationData", 256); + ClaimBuffer(MemoryArena, &ClaimedMemory, &Text, "Text", Kilobytes(4)); ClaimBuffer(MemoryArena, &ClaimedMemory, &Category, "Category", 256); CopyStringToBuffer(&AnnotationHeader, @@ -1053,7 +1088,7 @@ TimecodeToSeconds(Anno->time)); { HasFilterMenu = TRUE; } - BuildFilter(CategoriesArray, &UniqueCategories, "authored"); + BuildFilter(TopicsArray, &UniqueTopics, MediaArray, &UniqueMedia, "authored"); CopyStringToBuffer(&AnnotationClass, " authored"); CopyStringToBuffer(&Text, "%s ", @@ -1104,7 +1139,7 @@ Readable); { HasFilterMenu = TRUE; } - BuildFilter(CategoriesArray, &UniqueCategories, Anno->markers[MarkerIndex].marker); + BuildFilter(TopicsArray, &UniqueTopics, MediaArray, &UniqueMedia, Anno->markers[MarkerIndex].marker); BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, &HasMedium, Anno->markers[MarkerIndex].marker); } } @@ -1216,7 +1251,14 @@ AppendedIdentifier: } } - CopyStringToBuffer(&Text, "%d", RefIdentifier); + if(RefIndex > 1 && Anno->references[RefIndex].offset == Anno->references[RefIndex-1].offset) + { + CopyStringToBuffer(&Text, ",%d", RefIdentifier); + } + else + { + CopyStringToBuffer(&Text, "%d", RefIdentifier); + } ++RefIndex; ++RefIdentifier; @@ -1302,14 +1344,14 @@ Anno->time); } if(Anno->markers[MarkerIndex].marker) { - BuildFilter(CategoriesArray, &UniqueCategories, Anno->markers[MarkerIndex].marker); + BuildFilter(TopicsArray, &UniqueTopics, MediaArray, &UniqueMedia, Anno->markers[MarkerIndex].marker); } BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, &HasMedium, Anno->markers[MarkerIndex].marker); } if(!HasMedium) { - BuildFilter(CategoriesArray, &UniqueCategories, "default"); + BuildFilter(TopicsArray, &UniqueTopics, MediaArray, &UniqueMedia, "default"); BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, &HasMedium, "default"); } @@ -1442,10 +1484,15 @@ ReferencesArray[i].Identifier[j].Timecode); if(HasFilterMenu) { CopyStringToBuffer(&FilterState, "var filterState = {\n"); - for(int i = 0; i < UniqueCategories; ++i) + for(int i = 0; i < UniqueTopics; ++i) { CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", - CategoriesArray[i].Category, CategoriesArray[i].IsMedium ? "medium" : "topic"); + TopicsArray[i].Marker, "topic"); + } + for(int i = 0; i < UniqueMedia; ++i) + { + CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", + MediaArray[i].Marker, "medium"); } CopyStringToBuffer(&FilterState, "};\n" "\n"); @@ -1461,59 +1508,53 @@ ReferencesArray[i].Identifier[j].Timecode); bool HasTopic = FALSE; bool HasMedium = FALSE; - for(int i = 0; i < UniqueCategories; ++i) + for(int i = 0; i < UniqueTopics; ++i) { - if(CategoriesArray[i].IsMedium) + if(!HasTopic) { - 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, + CopyStringToBuffer(&FilterMenu, "
\n" "
Topics
\n"); - HasTopic = TRUE; - } + HasTopic = TRUE; + } CopyStringToBuffer(&FilterTopics, "
\n" " %s\n" "
\n", -CategoriesArray[i].Category, -CategoriesArray[i].Category, -CategoriesArray[i].Category); +TopicsArray[i].Marker, +TopicsArray[i].Marker, +TopicsArray[i].Marker); + } + + for(int i = 0; i < UniqueMedia; ++i) + { + if(!HasMedium) + { + CopyStringToBuffer(&FilterMedia, +"
\n" +"
Media
\n"); + + HasMedium = TRUE; } + + int j; + for(j = 0; j < ArrayCount(CategoryMedium); ++j) + { + if(!StringsDiffer(MediaArray[i].Marker, CategoryMedium[j][0])) + { + break; + } + } + + CopyStringToBuffer(&FilterMedia, +"
\n" +" %s%s\n" +"
\n", +MediaArray[i].Marker, +CategoryMedium[j][1], +CategoryMedium[j][2] +); } if(HasTopic) @@ -1561,6 +1602,7 @@ HMML.metadata.annotator); "\n" " \n" " \n" +" %s\n" // TODO(matt): Add the name of the project "\n" " \n" " \n" @@ -1568,7 +1610,9 @@ HMML.metadata.annotator); " \n" " \n" " \n" -" \n", HMML.metadata.project); +" \n", +HMML.metadata.title, +HMML.metadata.project); //NOTE(matt): Here is where we do all our CopyBuffer() calls CopyBuffer(&Master, &Title);