cinera.c: Add PROJECT_ID and THEME template tags

This commit is contained in:
Matt Mascarenhas 2018-06-12 20:03:12 +01:00
parent 4d495543f5
commit 0eeadd560b
2 changed files with 93 additions and 51 deletions

View File

@ -94,6 +94,8 @@ directory. Typical operation will involve setting these flags:
*Other available tags* *Other available tags*
- `<!-- __CINERA_PROJECT__ -->` _the full name of the project_ - `<!-- __CINERA_PROJECT__ -->` _the full name of the project_
- `<!-- __CINERA_PROJECT_ID__ -->` _the ID of the project_
- `<!-- __CINERA_THEME__ -->` _the theme of the project_
- `<!-- __CINERA_URL__ -->` _the URL where we have derived the page will be - `<!-- __CINERA_URL__ -->` _the URL where we have derived the page will be
publically accessibly, only really usable if BaseURL is set (-B)_ publically accessibly, only really usable if BaseURL is set (-B)_
- `<!-- __CINERA_CUSTOM0__ -->` - `<!-- __CINERA_CUSTOM0__ -->`

View File

@ -16,7 +16,7 @@ typedef struct
version CINERA_APP_VERSION = { version CINERA_APP_VERSION = {
.Major = 0, .Major = 0,
.Minor = 5, .Minor = 5,
.Patch = 57 .Patch = 58
}; };
// TODO(matt): Copy in the DB 3 stuff from cinera_working.c // TODO(matt): Copy in the DB 3 stuff from cinera_working.c
@ -260,7 +260,9 @@ typedef struct
char Custom14[MAX_CUSTOM_SNIPPET_LONG_LENGTH + 1]; char Custom14[MAX_CUSTOM_SNIPPET_LONG_LENGTH + 1];
char Custom15[MAX_CUSTOM_SNIPPET_LONG_LENGTH + 1]; char Custom15[MAX_CUSTOM_SNIPPET_LONG_LENGTH + 1];
char ProjectID[MAX_PROJECT_ID_LENGTH + 1];
char ProjectName[MAX_PROJECT_NAME_LENGTH + 1]; char ProjectName[MAX_PROJECT_NAME_LENGTH + 1];
char Theme[MAX_PROJECT_NAME_LENGTH + 1];
char Title[MAX_TITLE_LENGTH + 1]; char Title[MAX_TITLE_LENGTH + 1];
char URLIndex[MAX_BASE_URL_LENGTH + 1 + MAX_RELATIVE_PAGE_LOCATION_LENGTH + 1]; char URLIndex[MAX_BASE_URL_LENGTH + 1 + MAX_RELATIVE_PAGE_LOCATION_LENGTH + 1];
char URLPlayer[MAX_BASE_URL_LENGTH + 1 + MAX_RELATIVE_PAGE_LOCATION_LENGTH + 1 + MAX_PLAYER_URL_PREFIX_LENGTH + MAX_BASE_FILENAME_LENGTH + 1]; char URLPlayer[MAX_BASE_URL_LENGTH + 1 + MAX_RELATIVE_PAGE_LOCATION_LENGTH + 1 + MAX_PLAYER_URL_PREFIX_LENGTH + MAX_BASE_FILENAME_LENGTH + 1];
@ -304,6 +306,8 @@ enum
// Anywhere Optional // Anywhere Optional
TAG_PROJECT, TAG_PROJECT,
TAG_PROJECT_ID,
TAG_THEME,
TAG_URL, TAG_URL,
} template_tags; } template_tags;
@ -343,8 +347,10 @@ tag Tags[] = {
{ TAG_TITLE, "__CINERA_TITLE__" }, { TAG_TITLE, "__CINERA_TITLE__" },
{ TAG_VIDEO_ID, "__CINERA_VIDEO_ID__" }, { TAG_VIDEO_ID, "__CINERA_VIDEO_ID__" },
{ TAG_PROJECT, "__CINERA_PROJECT__" }, { TAG_PROJECT, "__CINERA_PROJECT__" },
{ TAG_URL, "__CINERA_URL__" }, { TAG_PROJECT_ID, "__CINERA_PROJECT_ID__" },
{ TAG_THEME, "__CINERA_THEME__" },
{ TAG_URL, "__CINERA_URL__" },
}; };
typedef struct typedef struct
@ -2360,6 +2366,8 @@ PrintUsage(char *BinaryLocation, config *DefaultConfig)
"\n" "\n"
" Other available tags:\n" " Other available tags:\n"
" <!-- __CINERA_PROJECT__ -->\n" " <!-- __CINERA_PROJECT__ -->\n"
" <!-- __CINERA_PROJECT_ID__ -->\n"
" <!-- __CINERA_THEME__ -->\n"
" <!-- __CINERA_URL__ -->\n" " <!-- __CINERA_URL__ -->\n"
" Only really usable if BaseURL is set \e[1;30m(-B)\e[0m\n" " Only really usable if BaseURL is set \e[1;30m(-B)\e[0m\n"
" <!-- __CINERA_CUSTOM0__ -->\n" " <!-- __CINERA_CUSTOM0__ -->\n"
@ -2407,6 +2415,11 @@ DepartComment(buffer *Template)
int int
ValidateTemplate(template **Template, char *Location, int TemplateType) ValidateTemplate(template **Template, char *Location, int TemplateType)
{ {
// TODO(matt): Record line numbers and contextual information:
// <? ?>
// <!-- -->
// < >
// <script </script>
#if 1 #if 1
int Return = ClaimTemplate(Template, Location, TemplateType); int Return = ClaimTemplate(Template, Location, TemplateType);
switch(Return) switch(Return)
@ -2964,7 +2977,6 @@ HMMLToBuffers(buffers *CollationBuffers, template **BespokeTemplate, char *Filen
*CollationBuffers->Custom14 = '\0'; *CollationBuffers->Custom14 = '\0';
*CollationBuffers->Custom15 = '\0'; *CollationBuffers->Custom15 = '\0';
*CollationBuffers->Title = '\0'; *CollationBuffers->Title = '\0';
*CollationBuffers->ProjectName = '\0';
char Filepath[256]; char Filepath[256];
if(Config.Edition == EDITION_PROJECT) if(Config.Edition == EDITION_PROJECT)
@ -3019,7 +3031,7 @@ HMMLToBuffers(buffers *CollationBuffers, template **BespokeTemplate, char *Filen
HaveErrors = TRUE; HaveErrors = TRUE;
} }
if(!HMML.metadata.project && !StringsDiffer(Config.Theme, "")) if(!HMML.metadata.project && !StringsDiffer(CollationBuffers->Theme, ""))
{ {
fprintf(stderr, "Unable to determine which theme to apply to the HTML\n" fprintf(stderr, "Unable to determine which theme to apply to the HTML\n"
"Please set at least one of:\n" "Please set at least one of:\n"
@ -3043,15 +3055,17 @@ HMMLToBuffers(buffers *CollationBuffers, template **BespokeTemplate, char *Filen
CopyString(CollationBuffers->URLPlayer, sizeof(CollationBuffers->URLPlayer), "%s", URLPlayer.Location); CopyString(CollationBuffers->URLPlayer, sizeof(CollationBuffers->URLPlayer), "%s", URLPlayer.Location);
DeclaimBuffer(&URLPlayer); DeclaimBuffer(&URLPlayer);
for(int ProjectIndex = 0; ProjectIndex < ArrayCount(ProjectInfo); ++ProjectIndex) if(HMML.metadata.project && (!StringsDiffer(CollationBuffers->ProjectID, "") || !StringsDiffer(CollationBuffers->ProjectName, "")))
{ {
if(!StringsDiffer(ProjectInfo[ProjectIndex].ProjectID, for(int ProjectIndex = 0; ProjectIndex < ArrayCount(ProjectInfo); ++ProjectIndex)
Config.Edition == EDITION_SINGLE && HMML.metadata.project ?
HMML.metadata.project :
Config.ProjectID))
{ {
CopyString(CollationBuffers->ProjectName, sizeof(CollationBuffers->ProjectName), "%s", ProjectInfo[ProjectIndex].FullName); if(!StringsDiffer(ProjectInfo[ProjectIndex].ProjectID,
break; HMML.metadata.project))
{
CopyString(CollationBuffers->ProjectID, sizeof(CollationBuffers->ProjectID), "%s", HMML.metadata.project);
CopyString(CollationBuffers->ProjectName, sizeof(CollationBuffers->ProjectName), "%s", ProjectInfo[ProjectIndex].FullName);
break;
}
} }
} }
@ -4444,12 +4458,25 @@ BuffersToHTML(buffers *CollationBuffers, template *Template, char *OutputPath, i
++j; ++j;
} }
// TODO(matt): Make this whole template stuff context-aware, so it can determine whether or not to HTML-encode
// or sanitise punctuation for CSS-safety
switch(Template->Metadata.Tag[i].TagCode) switch(Template->Metadata.Tag[i].TagCode)
{ {
case TAG_PROJECT_ID:
if(CollationBuffers->ProjectID[0] == '\0')
{
CopyStringToBufferNoFormat(&Output, CollationBuffers->ProjectID); // NOTE(matt): Not HTML-safe
}
else
{
fprintf(stderr, "Template contains a <!-- __CINERA_PROJECT_ID__ --> tag\n"
"Skipping just this tag, because no project ID is set\n");
}
break;
case TAG_PROJECT: case TAG_PROJECT:
if(CollationBuffers->ProjectName[0] == '\0') if(CollationBuffers->ProjectName[0] == '\0')
{ {
fprintf(stderr, "Template contains a <!-- __CINERA_PROJECT --> tag\n" fprintf(stderr, "Template contains a <!-- __CINERA_PROJECT__ --> tag\n"
"Skipping just this tag, because we do not know the project's full name\n"); "Skipping just this tag, because we do not know the project's full name\n");
} }
else else
@ -4457,6 +4484,9 @@ BuffersToHTML(buffers *CollationBuffers, template *Template, char *OutputPath, i
CopyStringToBufferHTMLSafe(&Output, CollationBuffers->ProjectName); CopyStringToBufferHTMLSafe(&Output, CollationBuffers->ProjectName);
} }
break; break;
case TAG_THEME:
CopyStringToBufferNoFormat(&Output, CollationBuffers->Theme); // NOTE(matt): Not HTML-safe
break;
case TAG_TITLE: case TAG_TITLE:
CopyStringToBufferHTMLSafe(&Output, CollationBuffers->Title); CopyStringToBufferHTMLSafe(&Output, CollationBuffers->Title);
break; break;
@ -4476,7 +4506,7 @@ BuffersToHTML(buffers *CollationBuffers, template *Template, char *OutputPath, i
case TAG_INDEX: case TAG_INDEX:
if(Config.Edition == EDITION_SINGLE) if(Config.Edition == EDITION_SINGLE)
{ {
fprintf(stderr, "Template contains a <!-- __CINERA_INDEX --> tag\n" fprintf(stderr, "Template contains a <!-- __CINERA_INDEX__ --> tag\n"
"Skipping just this tag, because an index cannot be generated for inclusion in a\n" "Skipping just this tag, because an index cannot be generated for inclusion in a\n"
"bespoke template in Single Edition\n"); "bespoke template in Single Edition\n");
} }
@ -6403,6 +6433,44 @@ main(int ArgC, char **Args)
exit(RC_SUCCESS); exit(RC_SUCCESS);
} }
// NOTE(matt): Init MemoryArena (it is global)
MemoryArena.Size = Megabytes(4);
if(!(MemoryArena.Location = calloc(MemoryArena.Size, 1)))
{
LogError(LOG_EMERGENCY, "%s: %s", Args[0], strerror(errno));
return RC_RIP;
}
MemoryArena.Ptr = MemoryArena.Location;
#if DEBUG_MEM
FILE *MemLog = fopen("/home/matt/cinera_mem", "a+");
fprintf(MemLog, " Allocated MemoryArena (%d)\n", MemoryArena.Size);
fclose(MemLog);
printf(" Allocated MemoryArena (%d)\n", MemoryArena.Size);
#endif
#if DEBUG
printf("Allocated MemoryArena: %d\n\n", MemoryArena.Size);
#endif
// NOTE(matt): Tree structure of buffer dependencies
// IncludesPlayer
// Menus
// Player
// ScriptPlayer
//
// IncludesIndex
// Index
buffers CollationBuffers = {};
if(ClaimBuffer(&CollationBuffers.IncludesPlayer, "IncludesPlayer", Kilobytes(1)) == RC_ARENA_FULL) { goto RIP; };
if(ClaimBuffer(&CollationBuffers.Menus, "Menus", Kilobytes(32)) == RC_ARENA_FULL) { goto RIP; };
if(ClaimBuffer(&CollationBuffers.Player, "Player", Kilobytes(256)) == RC_ARENA_FULL) { goto RIP; };
if(ClaimBuffer(&CollationBuffers.ScriptPlayer, "ScriptPlayer", Kilobytes(8)) == RC_ARENA_FULL) { goto RIP; };
if(ClaimBuffer(&CollationBuffers.IncludesIndex, "IncludesIndex", Kilobytes(1)) == RC_ARENA_FULL) { goto RIP; };
if(ClaimBuffer(&CollationBuffers.Search, "Search", Kilobytes(32)) == RC_ARENA_FULL) { goto RIP; };
bool HaveConfigErrors = FALSE; bool HaveConfigErrors = FALSE;
if(StringsDiffer(Config.ProjectID, "")) if(StringsDiffer(Config.ProjectID, ""))
{ {
@ -6419,6 +6487,15 @@ main(int ArgC, char **Args)
if(!StringsDiffer(Config.ProjectID, ProjectInfo[ProjectInfoIndex].ProjectID)) if(!StringsDiffer(Config.ProjectID, ProjectInfo[ProjectInfoIndex].ProjectID))
{ {
KnownProject = TRUE; KnownProject = TRUE;
CopyStringNoFormat(CollationBuffers.ProjectID, sizeof(CollationBuffers.ProjectID), Config.ProjectID);
if(!StringsDiffer(Config.Theme, ""))
{
CopyStringNoFormat(CollationBuffers.Theme, sizeof(CollationBuffers.Theme), Config.ProjectID);
}
if(StringsDiffer(ProjectInfo[ProjectInfoIndex].FullName, ""))
{
CopyStringNoFormat(CollationBuffers.ProjectName, sizeof(CollationBuffers.ProjectName), ProjectInfo[ProjectInfoIndex].FullName);
}
if(StringsDiffer(ProjectInfo[ProjectInfoIndex].Medium, "")) if(StringsDiffer(ProjectInfo[ProjectInfoIndex].Medium, ""))
{ {
Config.DefaultMedium = ProjectInfo[ProjectInfoIndex].Medium; Config.DefaultMedium = ProjectInfo[ProjectInfoIndex].Medium;
@ -6479,43 +6556,6 @@ main(int ArgC, char **Args)
if(HaveConfigErrors) { exit(RC_RIP); } if(HaveConfigErrors) { exit(RC_RIP); }
// NOTE(matt): Init MemoryArena (it is global)
MemoryArena.Size = Megabytes(4);
if(!(MemoryArena.Location = calloc(MemoryArena.Size, 1)))
{
LogError(LOG_EMERGENCY, "%s: %s", Args[0], strerror(errno));
return RC_RIP;
}
MemoryArena.Ptr = MemoryArena.Location;
#if DEBUG_MEM
FILE *MemLog = fopen("/home/matt/cinera_mem", "a+");
fprintf(MemLog, " Allocated MemoryArena (%d)\n", MemoryArena.Size);
fclose(MemLog);
printf(" Allocated MemoryArena (%d)\n", MemoryArena.Size);
#endif
#if DEBUG
printf("Allocated MemoryArena: %d\n\n", MemoryArena.Size);
#endif
// NOTE(matt): Tree structure of buffer dependencies
// IncludesPlayer
// Menus
// Player
// ScriptPlayer
//
// IncludesIndex
// Index
buffers CollationBuffers;
if(ClaimBuffer(&CollationBuffers.IncludesPlayer, "IncludesPlayer", Kilobytes(1)) == RC_ARENA_FULL) { goto RIP; };
if(ClaimBuffer(&CollationBuffers.Menus, "Menus", Kilobytes(32)) == RC_ARENA_FULL) { goto RIP; };
if(ClaimBuffer(&CollationBuffers.Player, "Player", Kilobytes(256)) == RC_ARENA_FULL) { goto RIP; };
if(ClaimBuffer(&CollationBuffers.ScriptPlayer, "ScriptPlayer", Kilobytes(8)) == RC_ARENA_FULL) { goto RIP; };
if(ClaimBuffer(&CollationBuffers.IncludesIndex, "IncludesIndex", Kilobytes(1)) == RC_ARENA_FULL) { goto RIP; };
if(ClaimBuffer(&CollationBuffers.Search, "Search", Kilobytes(32)) == RC_ARENA_FULL) { goto RIP; };
// NOTE(matt): Templating // NOTE(matt): Templating
// //
// Config will contain paths of multiple templates // Config will contain paths of multiple templates