hmml_to_html.c: Sort the filter media [#21]

This commit is contained in:
Matt Mascarenhas 2017-05-24 22:56:36 +01:00
parent f4352572b9
commit 2d9af4ee93
1 changed files with 154 additions and 110 deletions

View File

@ -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);