hmml_to_html.c: Generate the Filter [#21]
This commit is contained in:
parent
27143e291f
commit
3c32b5904b
|
@ -5,6 +5,10 @@ ctime -end ${0%.*}.ctm
|
||||||
exit
|
exit
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
|
// TODO(matt): Fully investigate the ClaimedMemory situation
|
||||||
|
|
||||||
typedef unsigned int bool;
|
typedef unsigned int bool;
|
||||||
|
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
|
@ -19,9 +23,18 @@ typedef struct
|
||||||
{
|
{
|
||||||
char *Location;
|
char *Location;
|
||||||
char *Ptr;
|
char *Ptr;
|
||||||
|
char *ID;
|
||||||
int Size;
|
int Size;
|
||||||
} buffer;
|
} 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
|
typedef struct
|
||||||
{
|
{
|
||||||
char Timecode[8];
|
char Timecode[8];
|
||||||
|
@ -42,19 +55,36 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char Date[32];
|
char Category[32];
|
||||||
char Text[512];
|
bool IsMedium;
|
||||||
} quote_info;
|
} category_info;
|
||||||
|
|
||||||
#define ArrayCount(A) sizeof(A)/sizeof(*(A))
|
#define ArrayCount(A) sizeof(A)/sizeof(*(A))
|
||||||
|
|
||||||
void
|
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->Location = MemoryArena + *ClaimedMemory;
|
||||||
Buffer->Size = Size;
|
Buffer->Size = Size;
|
||||||
|
Buffer->ID = ID;
|
||||||
*ClaimedMemory += Buffer->Size;
|
*ClaimedMemory += Buffer->Size;
|
||||||
|
*Buffer->Location = '\0';
|
||||||
Buffer->Ptr = Buffer->Location;
|
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
|
int
|
||||||
|
@ -95,6 +125,15 @@ CopyBuffer(buffer *Dest, buffer *Src)
|
||||||
Src->Ptr = Src->Location;
|
Src->Ptr = Src->Location;
|
||||||
while(*Src->Ptr)
|
while(*Src->Ptr)
|
||||||
{
|
{
|
||||||
|
// TODO(matt)
|
||||||
|
{
|
||||||
|
if(Dest->Ptr - Dest->Location >= Dest->Size)
|
||||||
|
{
|
||||||
|
printf("Too big! Too big!\n");
|
||||||
|
__asm__("int3");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
*Dest->Ptr++ = *Src->Ptr++;
|
*Dest->Ptr++ = *Src->Ptr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,10 +152,28 @@ __attribute__ ((format (printf, 2, 3)))
|
||||||
void
|
void
|
||||||
CopyStringToBuffer(buffer *Dest, char *Format, ...)
|
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_list Args;
|
||||||
va_start(Args, Format);
|
va_start(Args, Format);
|
||||||
int Length = vsprintf(Dest->Ptr, Format, Args);
|
int Length = vsprintf(Dest->Ptr, Format, Args);
|
||||||
va_end(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;
|
Dest->Ptr += Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,15 +292,6 @@ SanitisePunctuation(char *String)
|
||||||
return String;
|
return String;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *CategoryMedium[] =
|
|
||||||
{
|
|
||||||
"blackboard",
|
|
||||||
"owl",
|
|
||||||
"rant",
|
|
||||||
"research",
|
|
||||||
"run",
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
int
|
||||||
BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMML_Reference Ref, HMML_Annotation Anno)
|
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].ID, Ref.isbn);
|
||||||
CopyString(ReferencesArray[UniqueRefs].Source, Ref.author);
|
CopyString(ReferencesArray[UniqueRefs].Source, Ref.author);
|
||||||
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.title);
|
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);
|
CopyString(ReferencesArray[UniqueRefs].URL, "http://www.isbnsearch.org/isbn/%s", Ref.isbn);
|
||||||
}
|
}
|
||||||
else if(Ref.url && Ref.article && Ref.author)
|
else if(Ref.url && Ref.article && Ref.author)
|
||||||
|
@ -318,12 +367,48 @@ BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMM
|
||||||
return 0;
|
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
|
void
|
||||||
BuildCategories(buffer *AnnotationClass, buffer *Category, int *MarkerIndex, bool *HasCategory, char *Marker)
|
BuildCategories(buffer *AnnotationClass, buffer *Category, int *MarkerIndex, bool *HasCategory, char *Marker)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < ArrayCount(CategoryMedium); ++i)
|
for(int i = 0; i < ArrayCount(CategoryMedium); ++i)
|
||||||
{
|
{
|
||||||
if(!StringsDiffer(CategoryMedium[i], Marker))
|
if(!StringsDiffer(CategoryMedium[i][0], Marker))
|
||||||
{
|
{
|
||||||
CopyStringToBuffer(AnnotationClass, " %s", SanitisePunctuation(Marker));
|
CopyStringToBuffer(AnnotationClass, " %s", SanitisePunctuation(Marker));
|
||||||
++*MarkerIndex;
|
++*MarkerIndex;
|
||||||
|
@ -360,6 +445,11 @@ StringToInt(char *String)
|
||||||
int
|
int
|
||||||
BuildQuote(quote_info *Info, char *Speaker, int ID)
|
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";
|
char *QuoteDir = "/home/matt/git/GitHub/insofaras/25fc16d58a297a486334";
|
||||||
if(!StringsDiffer(Speaker, "handmade_hero"))
|
if(!StringsDiffer(Speaker, "handmade_hero"))
|
||||||
{
|
{
|
||||||
|
@ -385,12 +475,14 @@ BuildQuote(quote_info *Info, char *Speaker, int ID)
|
||||||
}
|
}
|
||||||
fread(Buffer, Length, 1, File);
|
fread(Buffer, Length, 1, File);
|
||||||
fclose(File);
|
fclose(File);
|
||||||
|
|
||||||
|
// TODO(matt): Search the quote store in reverse
|
||||||
char *InPtr = Buffer;
|
char *InPtr = Buffer;
|
||||||
|
|
||||||
while(InPtr - Buffer < Length)
|
while(InPtr - Buffer < Length)
|
||||||
{
|
{
|
||||||
char InID[4] = {0};
|
|
||||||
|
|
||||||
|
char InID[4] = { 0 };
|
||||||
char *OutPtr = InID;
|
char *OutPtr = InID;
|
||||||
while(*InPtr != ',')
|
while(*InPtr != ',')
|
||||||
{
|
{
|
||||||
|
@ -442,7 +534,7 @@ GenerateTopicColours(buffer *Colour, char *Topic)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < ArrayCount(CategoryMedium); ++i)
|
for(int i = 0; i < ArrayCount(CategoryMedium); ++i)
|
||||||
{
|
{
|
||||||
if(!StringsDiffer(Topic, CategoryMedium[i]))
|
if(!StringsDiffer(Topic, CategoryMedium[i][0]))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -450,6 +542,7 @@ GenerateTopicColours(buffer *Colour, char *Topic)
|
||||||
|
|
||||||
FILE *TopicsFile;
|
FILE *TopicsFile;
|
||||||
char *TopicsBuffer;
|
char *TopicsBuffer;
|
||||||
|
// TODO(matt): Consider (optionally) pulling this path from the config
|
||||||
if((TopicsFile = fopen("topics.css", "a+")))
|
if((TopicsFile = fopen("topics.css", "a+")))
|
||||||
{
|
{
|
||||||
fseek(TopicsFile, 0, SEEK_END);
|
fseek(TopicsFile, 0, SEEK_END);
|
||||||
|
@ -772,7 +865,7 @@ main(int ArgC, char **Args)
|
||||||
|
|
||||||
// NOTE(matt): Init MemoryArena
|
// NOTE(matt): Init MemoryArena
|
||||||
char *MemoryArena;
|
char *MemoryArena;
|
||||||
int ArenaSize = 1024 * 1024;
|
int ArenaSize = 1024 * 1024 * 4;
|
||||||
if(!(MemoryArena = calloc(ArenaSize, 1)))
|
if(!(MemoryArena = calloc(ArenaSize, 1)))
|
||||||
{
|
{
|
||||||
perror(Args[0]);
|
perror(Args[0]);
|
||||||
|
@ -790,6 +883,9 @@ main(int ArgC, char **Args)
|
||||||
buffer Title;
|
buffer Title;
|
||||||
buffer QuoteMenu;
|
buffer QuoteMenu;
|
||||||
buffer ReferenceMenu;
|
buffer ReferenceMenu;
|
||||||
|
buffer FilterMenu;
|
||||||
|
buffer FilterTopics;
|
||||||
|
buffer FilterMedia;
|
||||||
|
|
||||||
buffer Player;
|
buffer Player;
|
||||||
buffer Annotation;
|
buffer Annotation;
|
||||||
|
@ -800,6 +896,8 @@ main(int ArgC, char **Args)
|
||||||
buffer Category;
|
buffer Category;
|
||||||
buffer Colour;
|
buffer Colour;
|
||||||
|
|
||||||
|
buffer FilterState;
|
||||||
|
|
||||||
buffer Master;
|
buffer Master;
|
||||||
|
|
||||||
for(int FileIndex = 1; FileIndex < ArgC; ++FileIndex)
|
for(int FileIndex = 1; FileIndex < ArgC; ++FileIndex)
|
||||||
|
@ -816,7 +914,7 @@ main(int ArgC, char **Args)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG
|
#if CONFIG
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &Config, 1024);
|
ClaimBuffer(MemoryArena, &ClaimedMemory, &Config, "Config", 1024);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HMML_Output HMML = hmml_parse_file(InFile);
|
HMML_Output HMML = hmml_parse_file(InFile);
|
||||||
|
@ -824,16 +922,28 @@ main(int ArgC, char **Args)
|
||||||
|
|
||||||
if(HMML.well_formed)
|
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 };
|
ref_info ReferencesArray[200] = { 0 };
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &Player, 1024 * 256);
|
category_info CategoriesArray[64] = { 0 };
|
||||||
|
|
||||||
bool HasQuoteMenu = FALSE;
|
bool HasQuoteMenu = FALSE;
|
||||||
bool HasReferenceMenu = FALSE;
|
bool HasReferenceMenu = FALSE;
|
||||||
|
bool HasFilterMenu = FALSE;
|
||||||
|
|
||||||
int QuoteIdentifier = 0x3b1;
|
int QuoteIdentifier = 0x3b1;
|
||||||
int RefIdentifier = 1;
|
int RefIdentifier = 1;
|
||||||
int UniqueRefs = 0;
|
int UniqueRefs = 0;
|
||||||
|
int UniqueCategories = 0;
|
||||||
|
|
||||||
CopyStringToBuffer(&Title,
|
CopyStringToBuffer(&Title,
|
||||||
" <div class=\"title %s\">\n"
|
" <div class=\"title %s\">\n"
|
||||||
|
@ -846,6 +956,9 @@ main(int ArgC, char **Args)
|
||||||
|
|
||||||
for(int AnnotationIndex = 0; AnnotationIndex < HMML.annotation_count; ++AnnotationIndex)
|
for(int AnnotationIndex = 0; AnnotationIndex < HMML.annotation_count; ++AnnotationIndex)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("%d\n", AnnotationIndex);
|
||||||
|
#endif
|
||||||
HMML_Annotation *Anno = HMML.annotations + AnnotationIndex;
|
HMML_Annotation *Anno = HMML.annotations + AnnotationIndex;
|
||||||
bool HasCategory = FALSE;
|
bool HasCategory = FALSE;
|
||||||
bool HasQuote = FALSE;
|
bool HasQuote = FALSE;
|
||||||
|
@ -853,11 +966,10 @@ main(int ArgC, char **Args)
|
||||||
|
|
||||||
quote_info QuoteInfo = { 0 };
|
quote_info QuoteInfo = { 0 };
|
||||||
|
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationHeader, 512);
|
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationHeader, "AnnotationHeader", 512);
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &Category, 256);
|
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationClass, "AnnotationClass", 256);
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationClass, 256);
|
ClaimBuffer(MemoryArena, &ClaimedMemory, &Text, "Text", 1024 * 4);
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &Text, 1024 * 4);
|
ClaimBuffer(MemoryArena, &ClaimedMemory, &Colour, "Colour", 32);
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &Colour, 32);
|
|
||||||
|
|
||||||
CopyStringToBuffer(&AnnotationHeader,
|
CopyStringToBuffer(&AnnotationHeader,
|
||||||
" <div data-timestamp=\"%d\"",
|
" <div data-timestamp=\"%d\"",
|
||||||
|
@ -868,6 +980,11 @@ TimecodeToSeconds(Anno->time));
|
||||||
|
|
||||||
if(Anno->author)
|
if(Anno->author)
|
||||||
{
|
{
|
||||||
|
if(!HasFilterMenu)
|
||||||
|
{
|
||||||
|
HasFilterMenu = TRUE;
|
||||||
|
}
|
||||||
|
BuildFilter(CategoriesArray, &UniqueCategories, "authored");
|
||||||
CopyStringToBuffer(&AnnotationClass, " authored");
|
CopyStringToBuffer(&AnnotationClass, " authored");
|
||||||
CopyStringToBuffer(&Text,
|
CopyStringToBuffer(&Text,
|
||||||
"<span class=\"author\" style=\"color: %s;\">%s</span> ",
|
"<span class=\"author\" style=\"color: %s;\">%s</span> ",
|
||||||
|
@ -890,6 +1007,7 @@ Anno->author);
|
||||||
{
|
{
|
||||||
CopyStringToBuffer(&Text,
|
CopyStringToBuffer(&Text,
|
||||||
// TODO(matt): Hoverbox
|
// TODO(matt): Hoverbox
|
||||||
|
// We should get instructions on how to get this info in the config
|
||||||
"<a href=\"https://handmade.network/m/%s\" target=\"blank\" style=\"color: %s; text-decoration: none\">%.*s</a>",
|
"<a href=\"https://handmade.network/m/%s\" target=\"blank\" style=\"color: %s; text-decoration: none\">%.*s</a>",
|
||||||
Anno->markers[MarkerIndex].marker,
|
Anno->markers[MarkerIndex].marker,
|
||||||
StringToColourHash(&Colour, Anno->markers[MarkerIndex].marker),
|
StringToColourHash(&Colour, Anno->markers[MarkerIndex].marker),
|
||||||
|
@ -901,6 +1019,7 @@ StringLength(Readable), InPtr);
|
||||||
{
|
{
|
||||||
CopyStringToBuffer(&Text,
|
CopyStringToBuffer(&Text,
|
||||||
// TODO(matt): Hoverbox
|
// TODO(matt): Hoverbox
|
||||||
|
// We should get instructions on how to get this info in the config
|
||||||
"<a href=\"https://%s.handmade.network/\" target=\"blank\" style=\"color: %s; text-decoration: none\">%s</a>",
|
"<a href=\"https://%s.handmade.network/\" target=\"blank\" style=\"color: %s; text-decoration: none\">%s</a>",
|
||||||
Anno->markers[MarkerIndex].marker,
|
Anno->markers[MarkerIndex].marker,
|
||||||
StringToColourHash(&Colour, Anno->markers[MarkerIndex].marker),
|
StringToColourHash(&Colour, Anno->markers[MarkerIndex].marker),
|
||||||
|
@ -911,6 +1030,16 @@ Readable);
|
||||||
else if(Anno->markers[MarkerIndex].type == HMML_CATEGORY)
|
else if(Anno->markers[MarkerIndex].type == HMML_CATEGORY)
|
||||||
{
|
{
|
||||||
GenerateTopicColours(&Colour, Anno->markers[MarkerIndex].marker);
|
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);
|
BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, Anno->markers[MarkerIndex].marker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -921,8 +1050,6 @@ Readable);
|
||||||
HMML_Reference *CurrentRef = Anno->references + RefIndex;
|
HMML_Reference *CurrentRef = Anno->references + RefIndex;
|
||||||
if(!HasReferenceMenu)
|
if(!HasReferenceMenu)
|
||||||
{
|
{
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &ReferenceMenu, 1024 * 16);
|
|
||||||
|
|
||||||
CopyStringToBuffer(&ReferenceMenu,
|
CopyStringToBuffer(&ReferenceMenu,
|
||||||
" <div class=\"menu\">\n"
|
" <div class=\"menu\">\n"
|
||||||
" <span>References ▼</span>\n"
|
" <span>References ▼</span>\n"
|
||||||
|
@ -987,7 +1114,7 @@ Readable);
|
||||||
AppendedIdentifier:
|
AppendedIdentifier:
|
||||||
if(!HasReference)
|
if(!HasReference)
|
||||||
{
|
{
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, 128);
|
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, "AnnotationData", 128);
|
||||||
if(CurrentRef->isbn)
|
if(CurrentRef->isbn)
|
||||||
{
|
{
|
||||||
CopyStringToBuffer(&AnnotationData, " data-ref=\"%s", CurrentRef->isbn);
|
CopyStringToBuffer(&AnnotationData, " data-ref=\"%s", CurrentRef->isbn);
|
||||||
|
@ -1041,7 +1168,6 @@ AppendedIdentifier:
|
||||||
{
|
{
|
||||||
if(!HasQuoteMenu)
|
if(!HasQuoteMenu)
|
||||||
{
|
{
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &QuoteMenu, 1024 * 16);
|
|
||||||
CopyStringToBuffer(&QuoteMenu,
|
CopyStringToBuffer(&QuoteMenu,
|
||||||
" <div class=\"menu\">\n"
|
" <div class=\"menu\">\n"
|
||||||
" <span>Quotes ▼</span>\n"
|
" <span>Quotes ▼</span>\n"
|
||||||
|
@ -1053,7 +1179,7 @@ AppendedIdentifier:
|
||||||
|
|
||||||
if(!HasReference)
|
if(!HasReference)
|
||||||
{
|
{
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, 128);
|
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, "AnnotationData", 128);
|
||||||
CopyStringToBuffer(&AnnotationData, " data-ref=\"&#%d;", QuoteIdentifier);
|
CopyStringToBuffer(&AnnotationData, " data-ref=\"&#%d;", QuoteIdentifier);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1106,35 +1232,55 @@ Anno->time);
|
||||||
while(MarkerIndex < Anno->marker_count)
|
while(MarkerIndex < Anno->marker_count)
|
||||||
{
|
{
|
||||||
GenerateTopicColours(&Colour, Anno->markers[MarkerIndex].marker);
|
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);
|
BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, Anno->markers[MarkerIndex].marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyStringToBuffer(&AnnotationClass, "\"");
|
CopyStringToBuffer(&AnnotationClass, "\"");
|
||||||
CopyBuffer(&AnnotationHeader, &AnnotationClass);
|
CopyBuffer(&AnnotationHeader, &AnnotationClass);
|
||||||
ClaimedMemory -= AnnotationClass.Size;
|
|
||||||
|
|
||||||
if(HasQuote || HasReference)
|
if(HasQuote || HasReference)
|
||||||
{
|
{
|
||||||
CopyStringToBuffer(&AnnotationData, "\"");
|
CopyStringToBuffer(&AnnotationData, "\"");
|
||||||
CopyBuffer(&AnnotationHeader, &AnnotationData);
|
CopyBuffer(&AnnotationHeader, &AnnotationData);
|
||||||
ClaimedMemory -= AnnotationData.Size;
|
DeclaimBuffer(&AnnotationData, &ClaimedMemory);
|
||||||
}
|
}
|
||||||
CopyStringToBuffer(&AnnotationHeader, ">\n");
|
CopyStringToBuffer(&AnnotationHeader, ">\n");
|
||||||
|
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, 1024 * 4);
|
ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, "Annotation", 1024 * 8);
|
||||||
|
|
||||||
CopyBuffer(&Annotation, &AnnotationHeader);
|
CopyBuffer(&Annotation, &AnnotationHeader);
|
||||||
ClaimedMemory -= AnnotationHeader.Size;
|
|
||||||
CopyStringToBuffer(&Annotation,
|
CopyStringToBuffer(&Annotation,
|
||||||
" <div class=\"content\"><span class=\"timecode\">%s</span>",
|
" <div class=\"content\"><span class=\"timecode\">%s</span>",
|
||||||
Anno->time);
|
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)
|
if(HasCategory)
|
||||||
{
|
{
|
||||||
CopyStringToBuffer(&Category, "</span>");
|
CopyStringToBuffer(&Category, "</span>");
|
||||||
CopyBuffer(&Text, &Category);
|
CopyBuffer(&Text, &Category);
|
||||||
ClaimedMemory -= Category.Size;
|
DeclaimBuffer(&Category, &ClaimedMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
*Text.Ptr = '\0';
|
*Text.Ptr = '\0';
|
||||||
|
@ -1155,7 +1301,6 @@ Anno->time);
|
||||||
Anno->time);
|
Anno->time);
|
||||||
|
|
||||||
CopyBuffer(&Annotation, &Text);
|
CopyBuffer(&Annotation, &Text);
|
||||||
ClaimedMemory -= Text.Size;
|
|
||||||
|
|
||||||
CopyStringToBuffer(&Annotation, "</div>\n"
|
CopyStringToBuffer(&Annotation, "</div>\n"
|
||||||
" </div>\n"
|
" </div>\n"
|
||||||
|
@ -1163,16 +1308,22 @@ Anno->time);
|
||||||
|
|
||||||
CopyBuffer(&Player, &Annotation);
|
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)
|
if(HasQuoteMenu)
|
||||||
{
|
{
|
||||||
CopyStringToBuffer(&QuoteMenu,
|
CopyStringToBuffer(&QuoteMenu,
|
||||||
" </div>\n"
|
" </div>\n"
|
||||||
" </div>\n");
|
" </div>\n");
|
||||||
CopyBuffer(&Title, &QuoteMenu);
|
CopyBuffer(&Title, &QuoteMenu);
|
||||||
ClaimedMemory -= QuoteMenu.Size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(HasReferenceMenu)
|
if(HasReferenceMenu)
|
||||||
|
@ -1226,9 +1377,108 @@ ReferencesArray[i].Identifier[j].Timecode);
|
||||||
" </div>\n"
|
" </div>\n"
|
||||||
" </div>\n");
|
" </div>\n");
|
||||||
CopyBuffer(&Title, &ReferenceMenu);
|
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,
|
||||||
|
" <div class=\"menu filter\">\n"
|
||||||
|
" <span><img src=\"hues_HCL.png\"></span>\n"
|
||||||
|
" <div class=\"filter_container\">\n"
|
||||||
|
" <div class=\"filter_mode inclusive\">Filter mode: </div>\n"
|
||||||
|
" <div class=\"filters\">\n");
|
||||||
|
|
||||||
|
{
|
||||||
|
bool HasTopic = FALSE;
|
||||||
|
bool HasMedium = FALSE;
|
||||||
|
|
||||||
|
for(int i = 0; i < UniqueCategories; ++i)
|
||||||
|
{
|
||||||
|
if(CategoriesArray[i].IsMedium)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
" <div class=\"filter_topics\">\n"
|
||||||
|
" <div class=\"filter_title\">Topics</div>\n");
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(HasTopic)
|
||||||
|
{
|
||||||
|
CopyStringToBuffer(&FilterTopics,
|
||||||
|
" </div>\n");
|
||||||
|
CopyBuffer(&FilterMenu, &FilterTopics);
|
||||||
|
}
|
||||||
|
if(HasMedium)
|
||||||
|
{
|
||||||
|
CopyStringToBuffer(&FilterMedia,
|
||||||
|
" </div>\n");
|
||||||
|
CopyBuffer(&FilterMenu, &FilterMedia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CopyStringToBuffer(&FilterMenu,
|
||||||
|
" </div>\n"
|
||||||
|
" </div>\n"
|
||||||
|
" </div>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyBuffer(&Title, &FilterMenu);
|
||||||
|
|
||||||
#if CONFIG
|
#if CONFIG
|
||||||
// TODO(matt): Here is where I test ParseConfig
|
// TODO(matt): Here is where I test ParseConfig
|
||||||
ParseConfig(&Config, HMML.metadata.annotator);
|
ParseConfig(&Config, HMML.metadata.annotator);
|
||||||
|
@ -1243,8 +1493,10 @@ HMML.metadata.annotator);
|
||||||
" </div>\n");
|
" </div>\n");
|
||||||
|
|
||||||
//NOTE(matt): Collate the buffers!
|
//NOTE(matt): Collate the buffers!
|
||||||
|
#if DEBUG
|
||||||
|
printf("Buffer Collation\n\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
ClaimBuffer(MemoryArena, &ClaimedMemory, &Master, 1024 * 512);
|
|
||||||
CopyStringToBuffer(&Master,
|
CopyStringToBuffer(&Master,
|
||||||
"<html>\n"
|
"<html>\n"
|
||||||
" <head>\n"
|
" <head>\n"
|
||||||
|
@ -1260,9 +1512,7 @@ HMML.metadata.annotator);
|
||||||
|
|
||||||
//NOTE(matt): Here is where we do all our CopyBuffer() calls
|
//NOTE(matt): Here is where we do all our CopyBuffer() calls
|
||||||
CopyBuffer(&Master, &Title);
|
CopyBuffer(&Master, &Title);
|
||||||
ClaimedMemory -= Title.Size;
|
|
||||||
CopyBuffer(&Master, &Player);
|
CopyBuffer(&Master, &Player);
|
||||||
ClaimedMemory -= Player.Size;
|
|
||||||
//
|
//
|
||||||
|
|
||||||
CopyStringToBuffer(&Master,
|
CopyStringToBuffer(&Master,
|
||||||
|
@ -1299,6 +1549,292 @@ HMML.metadata.annotator);
|
||||||
" });\n"
|
" });\n"
|
||||||
"}\n"
|
"}\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"
|
||||||
|
" </script>\n"
|
||||||
|
" </body>\n"
|
||||||
|
"</html>\n");
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
CopyStringToBuffer(&Master,
|
||||||
|
" <script>\n"
|
||||||
|
" var player = new Player(document.querySelector(\".player_container\"), onRefChanged);\n"
|
||||||
|
" window.addEventListener(\"resize\", function() { player.updateSize(); });\n"
|
||||||
|
" document.addEventListener(\"keypress\", function(ev) {\n"
|
||||||
|
" switch (ev.key) {\n"
|
||||||
|
" case 'n':\n"
|
||||||
|
" case 'd':\n"
|
||||||
|
" case 's': {\n"
|
||||||
|
" player.jumpToNextMarker();\n"
|
||||||
|
" } break;\n"
|
||||||
|
"\n"
|
||||||
|
" case 'p':\n"
|
||||||
|
" case 'a':\n"
|
||||||
|
" case 'w': {\n"
|
||||||
|
" player.jumpToPrevMarker();\n"
|
||||||
|
" } break;\n"
|
||||||
|
" }\n"
|
||||||
|
"});\n"
|
||||||
|
"\n"
|
||||||
|
"var refTimecodes = document.querySelectorAll(\".refs .ref .timecode\");\n"
|
||||||
|
"for (var i = 0; i < refTimecodes.length; ++i) {\n"
|
||||||
|
" refTimecodes[i].addEventListener(\"click\", function(ev) {\n"
|
||||||
|
" if (player) {\n"
|
||||||
|
" var time = ev.currentTarget.getAttribute(\"data-timestamp\");\n"
|
||||||
|
" player.setTime(parseInt(time, 10));\n"
|
||||||
|
" player.play();\n"
|
||||||
|
" ev.preventDefault();\n"
|
||||||
|
" ev.stopPropagation();\n"
|
||||||
|
" return false;\n"
|
||||||
|
" }\n"
|
||||||
|
" });\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
"var refSources = document.querySelectorAll(\".refs .ref\");\n"
|
"var refSources = document.querySelectorAll(\".refs .ref\");\n"
|
||||||
"for (var i = 0; i < refSources.length; ++i) {\n"
|
"for (var i = 0; i < refSources.length; ++i) {\n"
|
||||||
" refSources[i].addEventListener(\"click\", function(ev) {\n"
|
" refSources[i].addEventListener(\"click\", function(ev) {\n"
|
||||||
|
@ -1343,6 +1879,7 @@ HMML.metadata.annotator);
|
||||||
" </script>\n"
|
" </script>\n"
|
||||||
" </body>\n"
|
" </body>\n"
|
||||||
"</html>\n");
|
"</html>\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
FILE *OutFile;
|
FILE *OutFile;
|
||||||
if(!(OutFile = fopen("out.html", "w")))
|
if(!(OutFile = fopen("out.html", "w")))
|
||||||
|
@ -1355,7 +1892,7 @@ HMML.metadata.annotator);
|
||||||
fwrite(Master.Location, Master.Ptr - Master.Location, 1, OutFile);
|
fwrite(Master.Location, Master.Ptr - Master.Location, 1, OutFile);
|
||||||
fclose(OutFile);
|
fclose(OutFile);
|
||||||
|
|
||||||
ClaimedMemory -= Master.Size;
|
DeclaimBuffer(&Master, &ClaimedMemory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
.title.riscy,
|
.title.riscy,
|
||||||
.title.riscy > .menu .refs,
|
.title.riscy > .menu .refs,
|
||||||
.title.riscy > .menu .filter,
|
.title.riscy > .menu .filter_container,
|
||||||
.title.riscy > .menu > .refs .ref,
|
.title.riscy > .menu > .refs .ref,
|
||||||
.title.riscy > .menu > .filter .filter_mode,
|
.title.riscy > .menu > .filter_container .filter_mode,
|
||||||
.markers_container.riscy,
|
.markers_container.riscy,
|
||||||
.markers_container.riscy > .marker {
|
.markers_container.riscy > .marker {
|
||||||
background-color: #EEE;
|
background-color: #EEE;
|
||||||
|
@ -23,8 +23,8 @@
|
||||||
|
|
||||||
.title.riscy > .menu:hover,
|
.title.riscy > .menu:hover,
|
||||||
.title.riscy > .menu > .refs .ref:hover,
|
.title.riscy > .menu > .refs .ref:hover,
|
||||||
.title.riscy > .menu > .filter .filter_mode:hover,
|
.title.riscy > .menu > .filter_container .filter_mode:hover,
|
||||||
.title.riscy > .menu > .filter .filter_content:hover,
|
.title.riscy > .menu > .filter_container .filter_content:hover,
|
||||||
.markers_container.riscy > .marker:hover > .content {
|
.markers_container.riscy > .marker:hover > .content {
|
||||||
background-color: #FFF8E7;
|
background-color: #FFF8E7;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
|
|
||||||
.title.riscy > .menu > .refs .ref .source,
|
.title.riscy > .menu > .refs .ref .source,
|
||||||
.title.riscy > .menu > .refs .ref .quote_byline,
|
.title.riscy > .menu > .refs .ref .quote_byline,
|
||||||
.title > .menu > .filter .filter_content.off .text {
|
.title > .menu > .filter_container .filter_content.off .text {
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,11 @@
|
||||||
* .markers_container.riscy > marker.run
|
* .markers_container.riscy > marker.run
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* TODO(matt): Actually style this */
|
@keyframes riscy_fade_mode {
|
||||||
|
0% { color: #FFF; }
|
||||||
|
100% { color: #000; }
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes riscy_fade_text {
|
@keyframes riscy_fade_text {
|
||||||
0% { color: #FFF; }
|
0% { color: #FFF; }
|
||||||
100% { color: #888; }
|
100% { color: #888; }
|
||||||
|
@ -107,12 +111,18 @@
|
||||||
100% { background-color: #EEE; }
|
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 {
|
.title.riscy .filter_content.responsible .text {
|
||||||
animation-name: riscy_fade_text;
|
animation-name: riscy_fade_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title.riscy > .menu.filter.responsible,
|
.title.riscy > .menu.filter.responsible,
|
||||||
.title.riscy .filter_content.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;
|
animation-name: riscy_fade_background;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,14 +29,14 @@
|
||||||
.title > .menu.filter.responsible,
|
.title > .menu.filter.responsible,
|
||||||
.title .filter_content.responsible,
|
.title .filter_content.responsible,
|
||||||
.title .filter_content.responsible .text,
|
.title .filter_content.responsible .text,
|
||||||
.title > .menu > .filter .filter_mode.responsible {
|
.title > .menu > .filter_container .filter_mode.responsible {
|
||||||
animation-duration: 8s;
|
animation-duration: 8s;
|
||||||
animation-timing-function: ease-out;
|
animation-timing-function: ease-out;
|
||||||
animation-iteration-count: 1;
|
animation-iteration-count: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu .refs,
|
.title > .menu .refs,
|
||||||
.title > .menu .filter {
|
.title > .menu .filter_container {
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -51,12 +51,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu:hover .refs,
|
.title > .menu:hover .refs,
|
||||||
.title > .menu:hover .filter {
|
.title > .menu:hover .filter_container {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .refs .ref,
|
.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;
|
border-bottom: 1px solid;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .refs .ref:last-child,
|
.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;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .refs .ref .ref_content,
|
.title > .menu > .refs .ref .ref_content,
|
||||||
.title > .menu > .refs .ref .filter_content {
|
.title > .menu > .filter_content {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -120,60 +120,60 @@
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_mode {
|
.title > .menu > .filter_container .filter_mode {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_mode.exclusive:after {
|
.title > .menu > .filter_container .filter_mode.exclusive:after {
|
||||||
content: "exclusive";
|
content: "exclusive";
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_mode.inclusive:after {
|
.title > .menu > .filter_container .filter_mode.inclusive:after {
|
||||||
content: "inclusive";
|
content: "inclusive";
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_title {
|
.title > .menu > .filter_container .filter_title {
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filters {
|
.title > .menu > .filter_container .filters {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row nowrap;
|
flex-flow: row nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filters > * {
|
.title > .menu > .filter_container .filters > * {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_content {
|
.title > .menu > .filter_container .filter_content {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_content .icon {
|
.title > .menu > .filter_container .filter_content .icon {
|
||||||
margin: 0 4px;
|
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;
|
margin: 0 .5em 0 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_content.off .icon {
|
.title > .menu > .filter_container .filter_content.off .icon {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_content.rant .icon {
|
.title > .menu > .filter_container .filter_content.rant .icon {
|
||||||
color: #F00;
|
color: #F00;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_media .filter_content.off .icon {
|
.title > .menu > .filter_container .filter_media .filter_content.off .icon {
|
||||||
opacity: 0.32;
|
opacity: 0.32;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_content.rant .text,
|
.title > .menu > .filter_container .filter_content.rant .text,
|
||||||
.markers_container > .marker.rant .content {
|
.markers_container > .marker.rant .content {
|
||||||
font-variant: small-caps;
|
font-variant: small-caps;
|
||||||
}
|
}
|
||||||
|
@ -254,18 +254,18 @@
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_content {
|
.title > .menu > .filter_container .filter_content {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_content .category,
|
.title > .menu > .filter_container .filter_content .category,
|
||||||
.markers_container > .marker .content .categories .category {
|
.markers_container > .marker .content .categories .category {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
height: 5px;
|
height: 5px;
|
||||||
width: 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 {
|
.markers_container > .marker .content .categories .category.off {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
@ -274,7 +274,7 @@
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title > .menu > .filter .filter_content .icon {
|
.title > .menu > .filter_container .filter_content .icon {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue