hmml_to_html.c: Correct integration [#25]

This commit is contained in:
Matt Mascarenhas 2017-06-13 23:13:03 +01:00
parent 0ad47c6c48
commit 811abe6271
1 changed files with 133 additions and 99 deletions

View File

@ -170,13 +170,16 @@ CopyString(char Dest[], char *Format, ...)
va_end(Args); va_end(Args);
} }
void int
CopyStringNoFormat(char *Dest, char *String) CopyStringNoFormat(char *Dest, char *String)
{ {
int Length = 0;
while(*String) while(*String)
{ {
*Dest++ = *String++; *Dest++ = *String++;
++Length;
} }
return Length;
} }
int int
@ -288,7 +291,7 @@ CopyStringToBufferCSVSafe(buffer *Dest, char *String)
} }
int int
StringsDiffer(char *A, char *B) StringsDiffer(char *A, char *B) // NOTE(matt): Two null-terminated strings
{ {
while(*A && *B && *A == *B) while(*A && *B && *A == *B)
{ {
@ -298,15 +301,19 @@ StringsDiffer(char *A, char *B)
} }
bool bool
StringsDifferL(char *A, char *B, int LengthofA) StringsDifferT(char *A, // NOTE(matt): Null-terminated string
char *B, // NOTE(matt): Not null-terminated string (e.g. one mid-buffer)
char Terminator // NOTE(matt): Caller definable terminator. Pass '\0' to only match on the extent of A
)
{ {
int ALength = StringLength(A);
int i = 0; int i = 0;
while(i < LengthofA && A[i] && A[i] == B[i]) while(i < ALength && A[i] && A[i] == B[i])
{ {
++i; ++i;
} }
// TODO(matt): Uncomment if((!Terminator && !A[i] && ALength == i) ||
if(!A[i] && LengthofA == i)// && (B[i] == ' ' || B[i] == '\"')) (!A[i] && ALength == i && (B[i] == Terminator)))
{ {
return FALSE; return FALSE;
} }
@ -705,7 +712,7 @@ BuildCategories(buffer *AnnotationClass, buffer *Category, int *MarkerIndex, boo
if(*Ptr == '\"') if(*Ptr == '\"')
{ {
++Ptr; ++Ptr;
if(!StringsDifferL(SanitisePunctuation(Marker), Ptr, StringLength(SanitisePunctuation(Marker)))) if(!StringsDifferT(SanitisePunctuation(Marker), Ptr, ' '))
{ {
Found = TRUE; Found = TRUE;
break; break;
@ -865,7 +872,7 @@ GenerateTopicColours(buffer *Colour, char *Topic)
while(TopicsPtr - TopicsBuffer < TopicsLength) while(TopicsPtr - TopicsBuffer < TopicsLength)
{ {
TopicsPtr += StringLength(".category."); TopicsPtr += StringLength(".category.");
if(!StringsDifferL(SanitisePunctuation(Topic), TopicsPtr, StringLength(Topic))) if(!StringsDifferT(SanitisePunctuation(Topic), TopicsPtr, ' '))
{ {
free(TopicsBuffer); free(TopicsBuffer);
fclose(TopicsFile); fclose(TopicsFile);
@ -1836,7 +1843,8 @@ ReferencesArray[i].Identifier[j].Timecode);
if(HasFilterMenu) if(HasFilterMenu)
{ {
CopyStringToBuffer(&FilterState, "var filterState = {\n"); CopyStringToBuffer(&FilterState,
" var filterState = {\n");
for(int i = 0; i < UniqueTopics; ++i) for(int i = 0; i < UniqueTopics; ++i)
{ {
CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n",
@ -1847,8 +1855,8 @@ ReferencesArray[i].Identifier[j].Timecode);
CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n",
MediaArray[i].Marker, "medium"); MediaArray[i].Marker, "medium");
} }
CopyStringToBuffer(&FilterState, "};\n" CopyStringToBuffer(&FilterState,
"\n"); " };\n");
CopyStringToBuffer(&FilterMenu, CopyStringToBuffer(&FilterMenu,
" <div class=\"menu filter\">\n" " <div class=\"menu filter\">\n"
@ -2177,9 +2185,7 @@ CategoryMedium[j][2]
" <script type=\"text/javascript\" src=\"player.js\"></script>\n" " <script type=\"text/javascript\" src=\"player.js\"></script>\n"
" <link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">\n" " <link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">\n"
" <link rel=\"stylesheet\" type=\"text/css\" href=\"%s.css\">\n" " <link rel=\"stylesheet\" type=\"text/css\" href=\"%s.css\">\n"
" <link rel=\"stylesheet\" type=\"text/css\" href=\"topics.css\">\n" " <link rel=\"stylesheet\" type=\"text/css\" href=\"topics.css\">\n",
" </head>\n"
" <body>\n",
HMML.metadata.project); HMML.metadata.project);
CopyStringToBuffer(&Script, CopyStringToBuffer(&Script,
@ -2260,8 +2266,8 @@ HMML.metadata.project);
" filterItemToggle(this);\n" " filterItemToggle(this);\n"
" });\n" " });\n"
"\n" "\n"
"%s\n" "%s"
"}\n" " }\n"
"}\n", FilterState.Location); "}\n", FilterState.Location);
} }
@ -2304,7 +2310,8 @@ HMML.metadata.project);
"var focusedElement = null;\n" "var focusedElement = null;\n"
"var focusedIdentifier = null;\n" "var focusedIdentifier = null;\n"
"\n" "\n"
"var player = new Player(document.querySelector(\".player_container\"), onRefChanged);\n" "var playerContainer = document.querySelector(\".player_container\")\n"
"var player = new Player(playerContainer, onRefChanged);\n"
"window.addEventListener(\"resize\", function() { player.updateSize(); });\n" "window.addEventListener(\"resize\", function() { player.updateSize(); });\n"
"document.addEventListener(\"keydown\", function(ev) {\n" "document.addEventListener(\"keydown\", function(ev) {\n"
" var key = ev.key;\n" " var key = ev.key;\n"
@ -2348,7 +2355,7 @@ HMML.metadata.project);
" });\n" " });\n"
"}\n" "}\n"
"\n" "\n"
"var testMarkers = document.querySelectorAll(\".marker\");\n" "var testMarkers = playerContainer.querySelectorAll(\".marker\");\n"
"\n" "\n"
"window.addEventListener(\"blur\", function(){\n" "window.addEventListener(\"blur\", function(){\n"
" document.getElementById(\"focus-warn\").style.display = \"block\";\n" " document.getElementById(\"focus-warn\").style.display = \"block\";\n"
@ -2358,7 +2365,7 @@ HMML.metadata.project);
" document.getElementById(\"focus-warn\").style.display = \"none\";\n" " document.getElementById(\"focus-warn\").style.display = \"none\";\n"
"});\n" "});\n"
"\n" "\n"
"var colouredItems = document.querySelectorAll(\".author, .member, .project\");\n" "var colouredItems = playerContainer.querySelectorAll(\".author, .member, .project\");\n"
"for(i = 0; i < colouredItems.length; ++i)\n" "for(i = 0; i < colouredItems.length; ++i)\n"
"{\n" "{\n"
" setTextLightness(colouredItems[i]);\n" " setTextLightness(colouredItems[i]);\n"
@ -2369,7 +2376,7 @@ HMML.metadata.project);
"{\n" "{\n"
" setDotLightness(topicDots[i]);\n" " setDotLightness(topicDots[i]);\n"
"}\n" "}\n"
" </script>\n"); " </script>");
// //
//NOTE(matt): Collate the buffers! //NOTE(matt): Collate the buffers!
#if DEBUG #if DEBUG
@ -2382,10 +2389,7 @@ HMML.metadata.project);
FILE *TemplateFile; FILE *TemplateFile;
if(!(TemplateFile = fopen("template.html", "r"))) if(!(TemplateFile = fopen("template.html", "r")))
{ {
perror(Args[0]); perror(Args[0]); hmml_free(&HMML); free(MemoryArena); return 1;
hmml_free(&HMML);
free(MemoryArena);
return 1;
} }
fseek(TemplateFile, 0, SEEK_END); fseek(TemplateFile, 0, SEEK_END);
@ -2394,10 +2398,7 @@ HMML.metadata.project);
char *TemplateBuffer; char *TemplateBuffer;
if(!(TemplateBuffer = malloc(TemplateSize))) if(!(TemplateBuffer = malloc(TemplateSize)))
{ {
perror(Args[0]); perror(Args[0]); hmml_free(&HMML); free(MemoryArena); return 1;
hmml_free(&HMML);
free(MemoryArena);
return 1;
} }
fread(TemplateBuffer, TemplateSize, 1, TemplateFile); fread(TemplateBuffer, TemplateSize, 1, TemplateFile);
fclose(TemplateFile); fclose(TemplateFile);
@ -2405,19 +2406,16 @@ HMML.metadata.project);
char *OutputBuffer; char *OutputBuffer;
if(!(OutputBuffer = malloc(TemplateSize + Master.Size))) if(!(OutputBuffer = malloc(TemplateSize + Master.Size)))
{ {
perror(Args[0]); perror(Args[0]); free(TemplateBuffer); hmml_free(&HMML); free(MemoryArena); return 1;
hmml_free(&HMML);
free(MemoryArena);
return 1;
} }
char *TemplatePtr = TemplateBuffer; char *TemplatePtr = TemplateBuffer;
char *OutputPtr = OutputBuffer; char *OutputPtr = OutputBuffer;
char *HeaderTag = "<!-- __CINERA_HEADER__ -->"; char *HeaderTag = "__CINERA_HEADER__";
char *TitleTag = "<!-- __CINERA_TITLE__ -->"; char *TitleTag = "__CINERA_TITLE__";
char *PlayerTag = "<!-- __CINERA_PLAYER__ -->"; char *PlayerTag = "__CINERA_PLAYER__";
char *ScriptTag = "<!-- __CINERA_SCRIPT__ -->"; char *ScriptTag = "__CINERA_SCRIPT__";
bool FoundHeader = FALSE; bool FoundHeader = FALSE;
bool FoundTitle = FALSE; bool FoundTitle = FALSE;
@ -2428,53 +2426,92 @@ HMML.metadata.project);
{ {
if(*TemplatePtr == '!') if(*TemplatePtr == '!')
{ {
if(OutputPtr > OutputBuffer) if((TemplatePtr > TemplateBuffer && TemplatePtr[-1] == '<') &&
(TemplatePtr+1 - TemplateBuffer < TemplateSize && TemplatePtr[1] == '-') &&
(TemplatePtr+2 - TemplateBuffer < TemplateSize && TemplatePtr[2] == '-'))
{ {
--OutputPtr; char *CommentStart = &OutputPtr[-1];
while(TemplatePtr - TemplateBuffer < TemplateSize && *TemplatePtr != '>')
{
if(*TemplatePtr == '_')
{
if(!(StringsDifferT(HeaderTag, TemplatePtr, '\0')))
{
if(FoundHeader == TRUE)
{
fprintf(stderr, "Template contains more than one <!-- __CINERA_HEADER__ --> tag\n");
free(TemplateBuffer); free(OutputBuffer); hmml_free(&HMML); free(MemoryArena); return 1;
} }
if(TemplatePtr > TemplateBuffer)
{
--TemplatePtr;
}
if(!(StringsDifferL(HeaderTag, TemplatePtr, StringLength(HeaderTag))))
{
FoundHeader = TRUE; FoundHeader = TRUE;
CopyStringNoFormat(OutputPtr, Header.Location); OutputPtr = CommentStart;
OutputPtr += Header.Ptr - Header.Location; OutputPtr += CopyStringNoFormat(OutputPtr, Header.Location);
}
else if(!(StringsDifferL(TitleTag, TemplatePtr, StringLength(TitleTag))))
{
FoundTitle = TRUE;
CopyStringNoFormat(OutputPtr, Title.Location);
OutputPtr += Title.Ptr - Title.Location;
}
else if(!(StringsDifferL(PlayerTag, TemplatePtr, StringLength(PlayerTag))))
{
FoundPlayer = TRUE;
CopyStringNoFormat(OutputPtr, Player.Location);
OutputPtr += Player.Ptr - Player.Location;
}
else if(!(StringsDifferL(ScriptTag, TemplatePtr, StringLength(ScriptTag))))
{
FoundScript = TRUE;
CopyStringNoFormat(OutputPtr, Script.Location);
OutputPtr += Script.Ptr - Script.Location;
}
else
{
++OutputPtr;
*OutputPtr++ = '!';
}
while(TemplatePtr - TemplateBuffer < TemplateSize && *TemplatePtr != '>') while(TemplatePtr - TemplateBuffer < TemplateSize && *TemplatePtr != '>')
{ {
++TemplatePtr; ++TemplatePtr;
} }
if(TemplatePtr - TemplateBuffer < TemplateSize) ++TemplatePtr;
}
else if(!(StringsDifferT(TitleTag, TemplatePtr, '\0')))
{
if(FoundTitle == TRUE)
{
fprintf(stderr, "Template contains more than one <!-- __CINERA_TITLE__ --> tag\n");
free(TemplateBuffer); free(OutputBuffer); hmml_free(&HMML); free(MemoryArena); return 1;
}
/* TODO(matt): Allow setting a Title format, e.g.
<-- __CINERA_TITLE__ "%s - HandmadeDev" -->
Where %s is replaced with the HMML.metadata.title
Perhaps it would be saner to do this in the config file
*/
FoundTitle = TRUE;
OutputPtr = CommentStart;
OutputPtr += CopyStringNoFormat(OutputPtr, Title.Location);
while(TemplatePtr - TemplateBuffer < TemplateSize && *TemplatePtr != '>')
{ {
++TemplatePtr; ++TemplatePtr;
} }
++TemplatePtr;
}
else if(!(StringsDifferT(PlayerTag, TemplatePtr, '\0')))
{
if(FoundPlayer == TRUE)
{
fprintf(stderr, "Template contains more than one <!-- __CINERA_PLAYER__ --> tag\n");
free(TemplateBuffer); free(OutputBuffer); hmml_free(&HMML); free(MemoryArena); return 1;
}
FoundPlayer = TRUE;
OutputPtr = CommentStart;
OutputPtr += CopyStringNoFormat(OutputPtr, Player.Location);
while(TemplatePtr - TemplateBuffer < TemplateSize && *TemplatePtr != '>')
{
++TemplatePtr;
}
++TemplatePtr;
}
else if(!(StringsDifferT(ScriptTag, TemplatePtr, '\0')))
{
if(FoundScript == TRUE)
{
fprintf(stderr, "Template contains more than one <!-- __CINERA_SCRIPT__ --> tag\n");
free(TemplateBuffer); free(OutputBuffer); hmml_free(&HMML); free(MemoryArena); return 1;
}
FoundScript = TRUE;
OutputPtr = CommentStart;
OutputPtr += CopyStringNoFormat(OutputPtr, Script.Location);
while(TemplatePtr - TemplateBuffer < TemplateSize && *TemplatePtr != '>')
{
++TemplatePtr;
}
++TemplatePtr;
}
}
*OutputPtr++ = *TemplatePtr++;
}
}
else
{
*OutputPtr++ = *TemplatePtr++;
}
} }
else else
{ {
@ -2487,22 +2524,19 @@ HMML.metadata.project);
FILE *OutFile; FILE *OutFile;
if(!(OutFile = fopen("out_integrated.html", "w"))) if(!(OutFile = fopen("out_integrated.html", "w")))
{ {
perror(Args[0]); perror(Args[0]); free(TemplateBuffer); free(OutputBuffer); hmml_free(&HMML); free(MemoryArena); return 1;
hmml_free(&HMML);
free(MemoryArena);
return 1;
} }
fwrite(OutputBuffer, OutputPtr - OutputBuffer, 1, OutFile); fwrite(OutputBuffer, OutputPtr - OutputBuffer, 1, OutFile);
fclose(OutFile); fclose(OutFile);
} }
else else
{ {
fprintf(stderr, "Template is missing necessary tags\n"); fprintf(stderr, "Template is missing necessary tags:\n");
free(TemplateBuffer); if(!FoundHeader) { fprintf(stderr, " <!-- __CINERA_HEADER__ -->\n"); }
free(OutputBuffer); if(!FoundTitle) { fprintf(stderr, " <!-- __CINERA_TITLE__ -->\n"); }
hmml_free(&HMML); if(!FoundPlayer) { fprintf(stderr, " <!-- __CINERA_PLAYER__ -->\n"); }
free(MemoryArena); if(!FoundScript) { fprintf(stderr, " <!-- __CINERA_SCRIPT__ -->\n"); }
return 1; free(TemplateBuffer); free(OutputBuffer); hmml_free(&HMML); free(MemoryArena); return 1;
} }
free(TemplateBuffer); free(TemplateBuffer);
@ -2517,30 +2551,28 @@ HMML.metadata.project);
//NOTE(matt): Here is where we do all our CopyBuffer() calls //NOTE(matt): Here is where we do all our CopyBuffer() calls
CopyBuffer(&Master, &Header); CopyBuffer(&Master, &Header);
CopyStringToBuffer(&Master,
" </head>\n"
" <body>\n");
CopyBuffer(&Master, &Title); CopyBuffer(&Master, &Title);
CopyBuffer(&Master, &Player); CopyBuffer(&Master, &Player);
CopyBuffer(&Master, &Script); CopyBuffer(&Master, &Script);
CopyStringToBuffer(&Master, "\n");
// //
CopyStringToBuffer(&Master, CopyStringToBuffer(&Master,
" </body>\n" " </body>\n"
"</html>\n"); "</html>\n");
FILE *OutFile; FILE *OutFile;
if(!(OutFile = fopen("out.html", "w"))) if(!(OutFile = fopen("out.html", "w")))
{ {
perror(Args[0]); perror(Args[0]); hmml_free(&HMML); free(MemoryArena); return 1;
hmml_free(&HMML);
free(MemoryArena);
return 1;
} }
fwrite(Master.Location, Master.Ptr - Master.Location, 1, OutFile); fwrite(Master.Location, Master.Ptr - Master.Location, 1, OutFile);
fclose(OutFile); fclose(OutFile);
} }
DeclaimBuffer(&Master, &ClaimedMemory);
// NOTE(matt): Tree structure of "global" buffer dependencies // NOTE(matt): Tree structure of "global" buffer dependencies
// FilterState // FilterState
// Script // Script
@ -2557,6 +2589,7 @@ HMML.metadata.project);
// QuoteMenu // QuoteMenu
// Title // Title
// Header // Header
// Master
DeclaimBuffer(&FilterState, &ClaimedMemory); DeclaimBuffer(&FilterState, &ClaimedMemory);
DeclaimBuffer(&Script, &ClaimedMemory); DeclaimBuffer(&Script, &ClaimedMemory);
@ -2575,6 +2608,7 @@ HMML.metadata.project);
DeclaimBuffer(&Title, &ClaimedMemory); DeclaimBuffer(&Title, &ClaimedMemory);
DeclaimBuffer(&Header, &ClaimedMemory); DeclaimBuffer(&Header, &ClaimedMemory);
DeclaimBuffer(&Master, &ClaimedMemory);
} }
else else
{ {