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 <stdlib.h> // NOTE(matt): calloc, malloc, free
#include "hmmlib.h"
//#include "config.h" // TODO(matt): Implement config.h
#define Kilobytes(Bytes) Bytes << 10
#define Megabytes(Bytes) Bytes << 20
@ -60,6 +61,16 @@ typedef struct
char WrittenText[32];
} 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))
void
@ -283,6 +294,118 @@ SanitisePunctuation(char *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
BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMML_Reference Ref, HMML_Annotation Anno)
{
@ -375,7 +498,6 @@ char *CategoryMedium[][3] =
void
BuildFilter(category_info *TopicsArray, int *UniqueTopics, category_info *MediaArray, int *UniqueMedia, char *Marker)
{
int Offset;
bool IsMedium = FALSE;
int i = 0;
@ -388,6 +510,7 @@ BuildFilter(category_info *TopicsArray, int *UniqueTopics, category_info *MediaA
}
}
int Offset;
if(IsMedium)
{
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)
{
CopyString(TopicsArray[i].Marker, Marker);
}
++*UniqueTopics;
return;
}
}
@ -605,7 +727,7 @@ GenerateTopicColours(buffer *Colour, char *Topic)
int TopicsLength = ftell(TopicsFile);
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)))
{
perror("GenerateTopicColours");
@ -963,6 +1085,9 @@ main(int ArgC, char **Args)
buffer FilterMenu;
buffer FilterTopics;
buffer FilterMedia;
buffer CreditsMenu;
buffer HostInfo;
buffer AnnotatorInfo;
buffer Player;
buffer Colour;
@ -1002,6 +1127,7 @@ main(int ArgC, char **Args)
// FilterMenu
// FilterTopics
// FilterMedia
// CreditsMenu
// Player
// Colour
// Annotation
@ -1015,6 +1141,9 @@ main(int ArgC, char **Args)
ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterMenu, "FilterMenu", Kilobytes(16));
ClaimBuffer(MemoryArena, &ClaimedMemory, &FilterTopics, "FilterTopics", 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, &Colour, "Colour", 32);
@ -1029,6 +1158,7 @@ main(int ArgC, char **Args)
bool HasQuoteMenu = FALSE;
bool HasReferenceMenu = FALSE;
bool HasFilterMenu = FALSE;
bool HasCreditsMenu = FALSE;
int QuoteIdentifier = 0x3b1;
int RefIdentifier = 1;
@ -1045,6 +1175,8 @@ main(int ArgC, char **Args)
" <div class=\"video_container\" data-videoId=\"%s\"></div>\n"
" <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
printf(" --- Entering Annotations Loop ---\n");
#endif
@ -1580,14 +1712,17 @@ CategoryMedium[j][2]
CopyBuffer(&Title, &FilterMenu);
if(HasCreditsMenu)
{
CopyBuffer(&Title, &CreditsMenu);
}
#if CONFIG
// TODO(matt): Here is where I test ParseConfig
ParseConfig(&Config, HMML.metadata.annotator);
#endif
CopyStringToBuffer(&Title,
" <span class=\"annotator_container\">Annotator: <span class=\"annotator\">%s</span></span>\n"
" </div>\n",
HMML.metadata.annotator);
" </div>\n");
CopyStringToBuffer(&Player,
" </div>\n"
@ -1602,7 +1737,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
" <title>%s</title>\n" // TODO(matt): Add the full name of the project, parsed from a config
"\n"
" <!-- Load the player -->\n"
" <script type=\"text/javascript\" src=\"player.js\"></script>\n"
@ -1667,6 +1802,9 @@ HMML.metadata.project);
// Annotation
// Colour
// Player
// AnnotatorInfo
// HostInfo
// CreditsMenu
// FilterMedia
// FilterTopics
// FilterMenu
@ -1679,6 +1817,9 @@ HMML.metadata.project);
DeclaimBuffer(&Colour, &ClaimedMemory);
DeclaimBuffer(&Player, &ClaimedMemory);
DeclaimBuffer(&AnnotatorInfo, &ClaimedMemory);
DeclaimBuffer(&HostInfo, &ClaimedMemory);
DeclaimBuffer(&CreditsMenu, &ClaimedMemory);
DeclaimBuffer(&FilterMedia, &ClaimedMemory);
DeclaimBuffer(&FilterTopics, &ClaimedMemory);
DeclaimBuffer(&FilterMenu, &ClaimedMemory);
@ -1919,87 +2060,6 @@ HMML.metadata.project);
" </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"
"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;
if(!(OutFile = fopen("out.html", "w")))
{

View File

@ -3,6 +3,8 @@
.title.riscy > .menu .filter_container,
.title.riscy > .menu > .refs .ref,
.title.riscy > .menu > .filter_container .filter_mode,
.title.riscy > .menu > .credits_container,
.title.riscy > .menu > .credits_container .credit,
.markers_container.riscy,
.markers_container.riscy > .marker {
background-color: #EEE;
@ -12,6 +14,7 @@
.title.riscy,
.title.riscy > .menu > .refs .ref,
.title.riscy > .menu > .refs .ref .timecode:hover::before,
.title.riscy > .menu > .credits_container .credit .name,
.markers_container.riscy > .marker > .content {
color: #000;
}
@ -46,7 +49,8 @@
.title.riscy > .menu > .refs .ref .source,
.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;
}
@ -69,6 +73,7 @@
/* Blackboard */
.title.riscy .filter_content.blackboard,
.markers_container.riscy .blackboard > .content,
.markers_container.riscy .off_blackboard > .content,
.markers_container.riscy > .marker.blackboard > .progress .content,
.markers_container.riscy > .marker:hover.blackboard > .faded .content {
background-size: 12px 12px;
@ -81,6 +86,11 @@
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 {
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);
@ -102,12 +112,12 @@
}
@keyframes riscy_fade_text {
0% { color: #FFF; }
0% { color: #000; }
100% { color: #888; }
}
@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; }
}

View File

@ -36,7 +36,8 @@
}
.title > .menu .refs,
.title > .menu .filter_container {
.title > .menu .filter_container,
.title > .menu .credits_container {
border: 1px solid;
border-top: none;
display: none;
@ -46,27 +47,54 @@
position: absolute;
right: 0;
top: 100%;
width: 350px;
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 .filter_container {
.title > .menu:hover .filter_container,
.title > .menu:hover .credits_container {
display: block;
}
.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;
padding: 10px;
display: flex;
flex-direction: column;
align-items: center;
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 .filter_container:last-child { /* TODO(matt): See what this is! */
.title > .menu > .credits_container .credit:last-child {
border: none;
}
@ -87,8 +115,9 @@
width: 100%;
}
.title > .menu > .refs .ref .quote_byline,
.title > .menu > .refs .ref .source,
.title > .menu > .refs .ref .quote_byline {
.title > .menu > .credits_container .credit .role {
font-size: 10px;
line-height: 8px;
}