hmml_to_html.c: Sort the filter media [#21]
This commit is contained in:
		
							parent
							
								
									f4352572b9
								
							
						
					
					
						commit
						2d9af4ee93
					
				|  | @ -17,6 +17,9 @@ typedef unsigned int bool; | |||
| #include <stdlib.h> // 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, | ||||
| "        <div class=\"title %s\">\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, | ||||
| "<span class=\"author\" style=\"color: %s;\">%s</span> ", | ||||
|  | @ -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, "<sup>%d</sup>", RefIdentifier); | ||||
|                         if(RefIndex > 1 && Anno->references[RefIndex].offset == Anno->references[RefIndex-1].offset) | ||||
|                         { | ||||
|                             CopyStringToBuffer(&Text, "<sup>,%d</sup>", RefIdentifier); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             CopyStringToBuffer(&Text, "<sup>%d</sup>", 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, | ||||
| "                        <div class=\"filter_media\">\n" | ||||
| "                            <div class=\"filter_title\">Media</div>\n"); | ||||
| 
 | ||||
|                                 HasMedium = TRUE; | ||||
|                             } | ||||
| 
 | ||||
|                             int j; | ||||
|                             for(j = 0; j < ArrayCount(CategoryMedium); ++j) | ||||
|                             { | ||||
|                                 if(!StringsDiffer(CategoriesArray[i].Category, CategoryMedium[j][0])) | ||||
|                                 { | ||||
|                                     break; | ||||
|                                 } | ||||
|                             } | ||||
| 
 | ||||
|                             CopyStringToBuffer(&FilterMedia, | ||||
| "                            <div class=\"filter_content %s\">\n" | ||||
| "                                <span class=\"icon\">%s</span><span class=\"text\">%s</span>\n" | ||||
| "                            </div>\n", | ||||
| CategoriesArray[i].Category, | ||||
| CategoryMedium[j][1], | ||||
| CategoryMedium[j][2] | ||||
| ); | ||||
| 
 | ||||
|                             /*
 | ||||
|                         </div> | ||||
|                              */ | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             if(!HasTopic) | ||||
|                             { | ||||
|                                 CopyStringToBuffer(&FilterMenu, | ||||
|                             CopyStringToBuffer(&FilterMenu, | ||||
| "                        <div class=\"filter_topics\">\n" | ||||
| "                            <div class=\"filter_title\">Topics</div>\n"); | ||||
| 
 | ||||
|                                 HasTopic = TRUE; | ||||
|                             } | ||||
|                             HasTopic = TRUE; | ||||
|                         } | ||||
|                         CopyStringToBuffer(&FilterTopics, | ||||
| "                            <div class=\"filter_content %s\">\n" | ||||
| "                                <span class=\"icon category %s\"></span><span class=\"text\">%s</span>\n" | ||||
| "                            </div>\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, | ||||
| "                        <div class=\"filter_media\">\n" | ||||
| "                            <div class=\"filter_title\">Media</div>\n"); | ||||
| 
 | ||||
|                             HasMedium = TRUE; | ||||
|                         } | ||||
| 
 | ||||
|                         int j; | ||||
|                         for(j = 0; j < ArrayCount(CategoryMedium); ++j) | ||||
|                         { | ||||
|                             if(!StringsDiffer(MediaArray[i].Marker, CategoryMedium[j][0])) | ||||
|                             { | ||||
|                                 break; | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         CopyStringToBuffer(&FilterMedia, | ||||
| "                            <div class=\"filter_content %s\">\n" | ||||
| "                                <span class=\"icon\">%s</span><span class=\"text\">%s</span>\n" | ||||
| "                            </div>\n", | ||||
| MediaArray[i].Marker, | ||||
| CategoryMedium[j][1], | ||||
| CategoryMedium[j][2] | ||||
| ); | ||||
|                     } | ||||
| 
 | ||||
|                     if(HasTopic) | ||||
|  | @ -1561,6 +1602,7 @@ HMML.metadata.annotator); | |||
| "<html>\n" | ||||
| "    <head>\n" | ||||
| "        <meta charset=\"UTF-8\">\n" | ||||
| "        <title>%s</title>\n" // TODO(matt): Add the name of the project
 | ||||
| "\n" | ||||
| "        <!-- Load the player -->\n" | ||||
| "        <script type=\"text/javascript\" src=\"player.js\"></script>\n" | ||||
|  | @ -1568,7 +1610,9 @@ HMML.metadata.annotator); | |||
| "        <link rel=\"stylesheet\" type=\"text/css\" href=\"%s.css\">\n" | ||||
| "        <link rel=\"stylesheet\" type=\"text/css\" href=\"topics.css\">\n" | ||||
| "    </head>\n" | ||||
| "    <body>\n", HMML.metadata.project); | ||||
| "    <body>\n", | ||||
| HMML.metadata.title, | ||||
| HMML.metadata.project); | ||||
| 
 | ||||
|             //NOTE(matt): Here is where we do all our CopyBuffer() calls
 | ||||
|             CopyBuffer(&Master, &Title); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue