hmml_to_html.c: Credits menu [#4]

This commit is contained in:
Matt Mascarenhas 2017-05-25 21:28:52 +01:00
parent 2d9af4ee93
commit 49f5a9e3ea
3 changed files with 198 additions and 99 deletions

View File

@ -16,6 +16,7 @@ typedef unsigned int bool;
#include <stdio.h> // NOTE(matt): printf, sprintf, vsprintf, fprintf, perror #include <stdio.h> // NOTE(matt): printf, sprintf, vsprintf, fprintf, perror
#include <stdlib.h> // NOTE(matt): calloc, malloc, free #include <stdlib.h> // NOTE(matt): calloc, malloc, free
#include "hmmlib.h" #include "hmmlib.h"
//#include "config.h" // TODO(matt): Implement config.h
#define Kilobytes(Bytes) Bytes << 10 #define Kilobytes(Bytes) Bytes << 10
#define Megabytes(Bytes) Bytes << 20 #define Megabytes(Bytes) Bytes << 20
@ -60,6 +61,16 @@ typedef struct
char WrittenText[32]; char WrittenText[32];
} category_info; } category_info;
// TODO(matt): Parse this stuff out of a config file
char *Credentials[ ][5] =
{
{ "Miblo", "Matt Mascarenhas", "http://miblodelcarpio.co.uk", "patreon_logo.png", "http://patreon.com/miblo"},
{ "miotatsu", "Mio Iwakura", "http://riscy.tv/", "patreon_logo.png", "http://patreon.com/miotatsu"},
{ "nothings", "Sean Barrett", "https://nothings.org/", "", ""},
{ "cmuratori", "Casey Muratori", "https://handmadehero.org", "patreon_logo.png", "http://patreon.com/cmuratori"},
{ "fierydrake", "Mike Tunnicliffe", "", "", ""},
};
#define ArrayCount(A) sizeof(A)/sizeof(*(A)) #define ArrayCount(A) sizeof(A)/sizeof(*(A))
void void
@ -283,6 +294,118 @@ SanitisePunctuation(char *String)
return String; return String;
} }
int
BuildCredits(buffer *CreditsMenu, buffer *HostInfo, buffer *AnnotatorInfo, bool *HasCreditsMenu, char *Host, char *Annotator)
{
bool FoundHost = FALSE;
bool FoundAnnotator = FALSE;
for(int CredentialIndex = 0; CredentialIndex < ArrayCount(Credentials); ++CredentialIndex)
{
if(!StringsDiffer(Host, Credentials[CredentialIndex][0]))
{
FoundHost = TRUE; // TODO(matt): Check if this is actually necessary...
CopyStringToBuffer(HostInfo,
" <span class=\"credit\">\n");
if(*Credentials[CredentialIndex][2])
{
CopyStringToBuffer(HostInfo,
" <a href=\"%s\" target=\"_blank\" class=\"person\">\n"
" <div class=\"role\">Host</div>\n"
" <div class=\"name\">%s</div>\n"
" </a>\n",
Credentials[CredentialIndex][2],
Credentials[CredentialIndex][1]);
}
else
{
CopyStringToBuffer(HostInfo,
" <div class=\"person\">\n"
" <div class=\"role\">Host</div>\n"
" <div class=\"name\">%s</div>\n"
" </div>\n",
Credentials[CredentialIndex][1]);
}
if(*Credentials[CredentialIndex][4] && *Credentials[CredentialIndex][3])
{
CopyStringToBuffer(HostInfo,
" <a class=\"support\" href=\"%s\"><img src=\"%s\"></a>\n",
Credentials[CredentialIndex][4],
Credentials[CredentialIndex][3]);
}
CopyStringToBuffer(HostInfo,
" </span>\n");
}
if(!StringsDiffer(Annotator, Credentials[CredentialIndex][0]))
{
FoundAnnotator = TRUE; // TODO(matt): Check if this is actually necessary...
CopyStringToBuffer(AnnotatorInfo,
" <span class=\"credit\">\n");
if(*Credentials[CredentialIndex][2])
{
CopyStringToBuffer(AnnotatorInfo,
" <a href=\"%s\" target=\"_blank\" class=\"person\">\n"
" <div class=\"role\">Annotator</div>\n"
" <div class=\"name\">%s</div>\n"
" </a>\n",
Credentials[CredentialIndex][2],
Credentials[CredentialIndex][1]);
}
else
{
CopyStringToBuffer(AnnotatorInfo,
" <div class=\"person\">\n"
" <div class=\"role\">Annotator</div>\n"
" <div class=\"name\">%s</div>\n"
" </div>\n",
Credentials[CredentialIndex][1]);
}
if(*Credentials[CredentialIndex][4] && *Credentials[CredentialIndex][3])
{
CopyStringToBuffer(AnnotatorInfo,
" <a class=\"support\" href=\"%s\"><img src=\"%s\"></a>\n",
Credentials[CredentialIndex][4],
Credentials[CredentialIndex][3]);
}
CopyStringToBuffer(AnnotatorInfo,
" </span>\n");
}
}
if(FoundHost || FoundAnnotator)
{
CopyStringToBuffer(CreditsMenu,
" <div class=\"menu\">\n"
" <div class=\"mouse_catcher\"></div>\n"
" <span>Credits</span>\n"
" <div class=\"credits_container\">\n");
if(FoundHost)
{
CopyBuffer(CreditsMenu, HostInfo);
}
if(FoundAnnotator)
{
CopyBuffer(CreditsMenu, AnnotatorInfo);
}
CopyStringToBuffer(CreditsMenu,
" </div>\n"
" </div>\n");
}
else
{
return 1;
}
*HasCreditsMenu = TRUE;
return 0;
}
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)
{ {
@ -375,7 +498,6 @@ char *CategoryMedium[][3] =
void void
BuildFilter(category_info *TopicsArray, int *UniqueTopics, category_info *MediaArray, int *UniqueMedia, char *Marker) BuildFilter(category_info *TopicsArray, int *UniqueTopics, category_info *MediaArray, int *UniqueMedia, char *Marker)
{ {
int Offset;
bool IsMedium = FALSE; bool IsMedium = FALSE;
int i = 0; int i = 0;
@ -388,6 +510,7 @@ BuildFilter(category_info *TopicsArray, int *UniqueTopics, category_info *MediaA
} }
} }
int Offset;
if(IsMedium) if(IsMedium)
{ {
int j = 0; int j = 0;
@ -443,14 +566,13 @@ BuildFilter(category_info *TopicsArray, int *UniqueTopics, category_info *MediaA
} }
} }
// This really ought to sort by the Alternative Text
if(i == *UniqueTopics) if(i == *UniqueTopics)
{ {
CopyString(TopicsArray[i].Marker, Marker); CopyString(TopicsArray[i].Marker, Marker);
} }
++*UniqueTopics; ++*UniqueTopics;
return;
} }
} }
@ -605,7 +727,7 @@ GenerateTopicColours(buffer *Colour, char *Topic)
int TopicsLength = ftell(TopicsFile); int TopicsLength = ftell(TopicsFile);
fseek(TopicsFile, 0, SEEK_SET); fseek(TopicsFile, 0, SEEK_SET);
// TODO(matt): May this not just ClaimBuffer? // TODO(matt): May this not just ClaimBuffer (if I can figure out how)?
if(!(TopicsBuffer = malloc(TopicsLength))) if(!(TopicsBuffer = malloc(TopicsLength)))
{ {
perror("GenerateTopicColours"); perror("GenerateTopicColours");
@ -963,6 +1085,9 @@ main(int ArgC, char **Args)
buffer FilterMenu; buffer FilterMenu;
buffer FilterTopics; buffer FilterTopics;
buffer FilterMedia; buffer FilterMedia;
buffer CreditsMenu;
buffer HostInfo;
buffer AnnotatorInfo;
buffer Player; buffer Player;
buffer Colour; buffer Colour;
@ -1002,6 +1127,7 @@ main(int ArgC, char **Args)
// FilterMenu // FilterMenu
// FilterTopics // FilterTopics
// FilterMedia // FilterMedia
// CreditsMenu
// Player // Player
// Colour // Colour
// Annotation // Annotation
@ -1015,6 +1141,9 @@ main(int ArgC, char **Args)
ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterMenu, "FilterMenu", Kilobytes(16)); ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterMenu, "FilterMenu", Kilobytes(16));
ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterTopics, "FilterTopics", Kilobytes(8)); ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterTopics, "FilterTopics", Kilobytes(8));
ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterMedia, "FilterMedia", Kilobytes(8)); ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterMedia, "FilterMedia", Kilobytes(8));
ClaimBuffer(MemoryArena, &ClaimedMemory, &CreditsMenu, "CreditsMenu", Kilobytes(8));
ClaimBuffer(MemoryArena, &ClaimedMemory, &HostInfo, "HostInfo", Kilobytes(1));
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotatorInfo, "AnnotatorInfo", Kilobytes(1));
ClaimBuffer(MemoryArena, &ClaimedMemory, &Player, "Player", Kilobytes(256)); ClaimBuffer(MemoryArena, &ClaimedMemory, &Player, "Player", Kilobytes(256));
ClaimBuffer(MemoryArena, &ClaimedMemory, &Colour, "Colour", 32); ClaimBuffer(MemoryArena, &ClaimedMemory, &Colour, "Colour", 32);
@ -1029,6 +1158,7 @@ main(int ArgC, char **Args)
bool HasQuoteMenu = FALSE; bool HasQuoteMenu = FALSE;
bool HasReferenceMenu = FALSE; bool HasReferenceMenu = FALSE;
bool HasFilterMenu = FALSE; bool HasFilterMenu = FALSE;
bool HasCreditsMenu = FALSE;
int QuoteIdentifier = 0x3b1; int QuoteIdentifier = 0x3b1;
int RefIdentifier = 1; int RefIdentifier = 1;
@ -1045,6 +1175,8 @@ main(int ArgC, char **Args)
" <div class=\"video_container\" data-videoId=\"%s\"></div>\n" " <div class=\"video_container\" data-videoId=\"%s\"></div>\n"
" <div class=\"markers_container %s\">\n", HMML.metadata.id, HMML.metadata.project); " <div class=\"markers_container %s\">\n", HMML.metadata.id, HMML.metadata.project);
BuildCredits(&CreditsMenu, &HostInfo, &AnnotatorInfo, &HasCreditsMenu, HMML.metadata.member, HMML.metadata.annotator);
#if DEBUG #if DEBUG
printf(" --- Entering Annotations Loop ---\n"); printf(" --- Entering Annotations Loop ---\n");
#endif #endif
@ -1580,14 +1712,17 @@ CategoryMedium[j][2]
CopyBuffer(&Title, &FilterMenu); CopyBuffer(&Title, &FilterMenu);
if(HasCreditsMenu)
{
CopyBuffer(&Title, &CreditsMenu);
}
#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);
#endif #endif
CopyStringToBuffer(&Title, CopyStringToBuffer(&Title,
" <span class=\"annotator_container\">Annotator: <span class=\"annotator\">%s</span></span>\n" " </div>\n");
" </div>\n",
HMML.metadata.annotator);
CopyStringToBuffer(&Player, CopyStringToBuffer(&Player,
" </div>\n" " </div>\n"
@ -1602,7 +1737,7 @@ HMML.metadata.annotator);
"<html>\n" "<html>\n"
" <head>\n" " <head>\n"
" <meta charset=\"UTF-8\">\n" " <meta charset=\"UTF-8\">\n"
" <title>%s</title>\n" // TODO(matt): Add the name of the project " <title>%s</title>\n" // TODO(matt): Add the full name of the project, parsed from a config
"\n" "\n"
" <!-- Load the player -->\n" " <!-- Load the player -->\n"
" <script type=\"text/javascript\" src=\"player.js\"></script>\n" " <script type=\"text/javascript\" src=\"player.js\"></script>\n"
@ -1667,6 +1802,9 @@ HMML.metadata.project);
// Annotation // Annotation
// Colour // Colour
// Player // Player
// AnnotatorInfo
// HostInfo
// CreditsMenu
// FilterMedia // FilterMedia
// FilterTopics // FilterTopics
// FilterMenu // FilterMenu
@ -1679,6 +1817,9 @@ HMML.metadata.project);
DeclaimBuffer(&Colour, &ClaimedMemory); DeclaimBuffer(&Colour, &ClaimedMemory);
DeclaimBuffer(&Player, &ClaimedMemory); DeclaimBuffer(&Player, &ClaimedMemory);
DeclaimBuffer(&AnnotatorInfo, &ClaimedMemory);
DeclaimBuffer(&HostInfo, &ClaimedMemory);
DeclaimBuffer(&CreditsMenu, &ClaimedMemory);
DeclaimBuffer(&FilterMedia, &ClaimedMemory); DeclaimBuffer(&FilterMedia, &ClaimedMemory);
DeclaimBuffer(&FilterTopics, &ClaimedMemory); DeclaimBuffer(&FilterTopics, &ClaimedMemory);
DeclaimBuffer(&FilterMenu, &ClaimedMemory); DeclaimBuffer(&FilterMenu, &ClaimedMemory);
@ -1919,87 +2060,6 @@ HMML.metadata.project);
" </body>\n" " </body>\n"
"</html>\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"
"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 onRefChanged(ref) {\n"
" var sourceMenus = document.querySelectorAll(\".menu\");\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");
#endif
FILE *OutFile; FILE *OutFile;
if(!(OutFile = fopen("out.html", "w"))) if(!(OutFile = fopen("out.html", "w")))
{ {

View File

@ -3,6 +3,8 @@
.title.riscy > .menu .filter_container, .title.riscy > .menu .filter_container,
.title.riscy > .menu > .refs .ref, .title.riscy > .menu > .refs .ref,
.title.riscy > .menu > .filter_container .filter_mode, .title.riscy > .menu > .filter_container .filter_mode,
.title.riscy > .menu > .credits_container,
.title.riscy > .menu > .credits_container .credit,
.markers_container.riscy, .markers_container.riscy,
.markers_container.riscy > .marker { .markers_container.riscy > .marker {
background-color: #EEE; background-color: #EEE;
@ -12,6 +14,7 @@
.title.riscy, .title.riscy,
.title.riscy > .menu > .refs .ref, .title.riscy > .menu > .refs .ref,
.title.riscy > .menu > .refs .ref .timecode:hover::before, .title.riscy > .menu > .refs .ref .timecode:hover::before,
.title.riscy > .menu > .credits_container .credit .name,
.markers_container.riscy > .marker > .content { .markers_container.riscy > .marker > .content {
color: #000; color: #000;
} }
@ -46,7 +49,8 @@
.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_container .filter_content.off .text { .title.riscy > .menu > .filter_container .filter_content.off .text,
.title.riscy > .menu > .credits_container .credit .role {
color: #888; color: #888;
} }
@ -69,6 +73,7 @@
/* Blackboard */ /* Blackboard */
.title.riscy .filter_content.blackboard, .title.riscy .filter_content.blackboard,
.markers_container.riscy .blackboard > .content, .markers_container.riscy .blackboard > .content,
.markers_container.riscy .off_blackboard > .content,
.markers_container.riscy > .marker.blackboard > .progress .content, .markers_container.riscy > .marker.blackboard > .progress .content,
.markers_container.riscy > .marker:hover.blackboard > .faded .content { .markers_container.riscy > .marker:hover.blackboard > .faded .content {
background-size: 12px 12px; background-size: 12px 12px;
@ -81,6 +86,11 @@
linear-gradient(to bottom, rgba(51, 153, 255, .16) 1px, transparent 1px); linear-gradient(to bottom, rgba(51, 153, 255, .16) 1px, transparent 1px);
} }
.markers_container.riscy .off_blackboard > .content {
background-image: linear-gradient(to right , rgba(51, 153, 255, .08) 1px, transparent 1px),
linear-gradient(to bottom, rgba(51, 153, 255, .08) 1px, transparent 1px);
}
.markers_container.riscy > .marker.blackboard > .progress .content { .markers_container.riscy > .marker.blackboard > .progress .content {
background-image: linear-gradient(to right , rgba(255, 255, 255, .16) 1px, transparent 1px), background-image: linear-gradient(to right , rgba(255, 255, 255, .16) 1px, transparent 1px),
linear-gradient(to bottom, rgba(255, 255, 255, .16) 1px, transparent 1px); linear-gradient(to bottom, rgba(255, 255, 255, .16) 1px, transparent 1px);
@ -102,12 +112,12 @@
} }
@keyframes riscy_fade_text { @keyframes riscy_fade_text {
0% { color: #FFF; } 0% { color: #000; }
100% { color: #888; } 100% { color: #888; }
} }
@keyframes riscy_fade_background { @keyframes riscy_fade_background {
0% { background-color: rgba(42, 49, 114, 0.7); } 0% { background-color: rgba(246, 178, 26, 0.8);}
100% { background-color: #EEE; } 100% { background-color: #EEE; }
} }

View File

@ -36,7 +36,8 @@
} }
.title > .menu .refs, .title > .menu .refs,
.title > .menu .filter_container { .title > .menu .filter_container,
.title > .menu .credits_container {
border: 1px solid; border: 1px solid;
border-top: none; border-top: none;
display: none; display: none;
@ -46,27 +47,54 @@
position: absolute; position: absolute;
right: 0; right: 0;
top: 100%; top: 100%;
width: 350px;
z-index: 1; z-index: 1;
} }
.title > .menu .refs,
.title > .menu .filter_container {
width: 350px;
}
.title > .menu .credits_container {
min-width: 240px;
}
.title > .menu:hover .refs, .title > .menu:hover .refs,
.title > .menu:hover .filter_container { .title > .menu:hover .filter_container,
.title > .menu:hover .credits_container {
display: block; display: block;
} }
.title > .menu > .refs .ref, .title > .menu > .refs .ref,
.title > .menu > .refs .filter_container { /* TODO(matt): See what this is! */ .title > .menu > .refs .filter_container, /* TODO(matt): See what this is! */
.title > .menu > .credits_container .credit {
border-bottom: 1px solid; border-bottom: 1px solid;
padding: 10px; padding: 10px;
display: flex; display: flex;
flex-direction: column;
align-items: center; align-items: center;
text-decoration: none; text-decoration: none;
} }
.title > .menu > .refs .ref,
.title > .menu > .refs .filter_container { /* TODO(matt): See what this is! */
flex-direction: column;
}
.title > .menu > .credits_container .credit {
flex-direction: row;
justify-content: space-between;
}
.title > .menu > .credits_container .credit .person {
text-decoration: none;
}
.title > .menu > .credits_container .credit .support {
margin: 4px;
}
.title > .menu > .refs .ref:last-child, .title > .menu > .refs .ref:last-child,
.title > .menu > .refs .filter_container:last-child { /* TODO(matt): See what this is! */ .title > .menu > .credits_container .credit:last-child {
border: none; border: none;
} }
@ -87,8 +115,9 @@
width: 100%; width: 100%;
} }
.title > .menu > .refs .ref .quote_byline,
.title > .menu > .refs .ref .source, .title > .menu > .refs .ref .source,
.title > .menu > .refs .ref .quote_byline { .title > .menu > .credits_container .credit .role {
font-size: 10px; font-size: 10px;
line-height: 8px; line-height: 8px;
} }