From 6f751dd2b2208f41f16cc5c0c2d8c3990b89a18b Mon Sep 17 00:00:00 2001 From: Matt Mascarenhas Date: Thu, 7 Dec 2017 21:07:36 +0000 Subject: [PATCH] cinera.c: Add support for alternative URL prefixes This is hardcoded for now, for ease of use, pending the config system Also add Medium to the ProjectInfo array, to save users having to set this with -m (which option remains available to them) Reorganise the CSS, Images and JS files back to their location in the same directory, since a default invocation of the program assumes they are in the same directory as the Root Directory, to hopefully alleviate some potential user frustration thanks to the requirement to set their locations (with -c, -i and -j) before any usable output is produced --- cinera/cinera.c | 297 ++++++++++-------- cinera/{css => }/cinera.css | 0 cinera/{images => }/cinera_icon_filter.png | Bin cinera/{js => }/cinera_player_post.js | 0 cinera/{js => }/cinera_player_pre.js | 0 cinera/{js => }/cinera_search.js | 13 +- cinera/{images => }/cinera_sprite_patreon.png | Bin 7 files changed, 173 insertions(+), 137 deletions(-) rename cinera/{css => }/cinera.css (100%) rename cinera/{images => }/cinera_icon_filter.png (100%) rename cinera/{js => }/cinera_player_post.js (100%) rename cinera/{js => }/cinera_player_pre.js (100%) rename cinera/{js => }/cinera_search.js (96%) rename cinera/{images => }/cinera_sprite_patreon.png (100%) diff --git a/cinera/cinera.c b/cinera/cinera.c index e17809f..8a56577 100644 --- a/cinera/cinera.c +++ b/cinera/cinera.c @@ -14,7 +14,7 @@ typedef struct version CINERA_APP_VERSION = { .Major = 0, .Minor = 5, - .Patch = 5 + .Patch = 6 }; #define CINERA_DB_VERSION 1 @@ -115,6 +115,8 @@ typedef struct char *OutLocation; char *OutIntegratedLocation; char *ProjectDir; + char *URLPrefix; /* NOTE(matt): This will become a full blown customisable output URL. + For now it simply replaces the ProjectID */ } config; typedef struct @@ -342,25 +344,28 @@ typedef struct char *ProjectID; char *FullName; char *Unit; // e.g. Day, Episode, Session - int NumberingScheme; + int NumberingScheme; // numbering_schemes + char *Medium; + char *AltURLPrefix; // NOTE(matt): This currently just straight up replaces the ProjectID in the player pages' output directories } project_info; project_info ProjectInfo[] = { - { "book", "Book Club", "Day", NS_LINEAR }, - { "riscy", "RISCY BUSINESS", "Day", NS_LINEAR }, + { "book", "Book Club", "Day", NS_LINEAR, "research", "" }, + { "pcalc", "pcalc", "Day", NS_LINEAR, "programming", "" }, + { "riscy", "RISCY BUSINESS", "Day", NS_LINEAR, "programming", "" }, - { "chat", "Handmade Chat", "Day", NS_LINEAR }, - { "code", "Handmade Hero", "Day", NS_LINEAR }, - { "intro-to-c", "Intro to C on Windows", "Day", NS_LINEAR }, - { "misc", "Handmade Miscellany", "", NS_LINEAR }, - { "ray", "Handmade Ray", "Day", NS_LINEAR }, + { "chat", "Handmade Chat", "Day", NS_LINEAR, "speech", "" }, + { "code", "Handmade Hero", "Day", NS_LINEAR, "programming", "day" }, + { "intro-to-c", "Intro to C on Windows", "Day", NS_LINEAR, "programming", "day" }, + { "misc", "Handmade Miscellany", "", NS_LINEAR, "admin", "" }, + { "ray", "Handmade Ray", "Day", NS_LINEAR, "programming", "" }, - { "hmdshow", "HandmadeDev Show", "", NS_SEASONAL }, + { "hmdshow", "HandmadeDev Show", "", NS_SEASONAL, "speech", "" }, - { "obbg", "Open Block Building Game", "Episode", NS_LINEAR }, + { "obbg", "Open Block Building Game", "Episode", NS_LINEAR, "programming", "" }, - { "sysadmin", "SysAdmin", "Session", NS_LINEAR }, + { "sysadmin", "SysAdmin", "Session", NS_LINEAR, "admin", "" }, }; #define ArrayCount(A) sizeof(A)/sizeof(*(A)) @@ -887,6 +892,62 @@ SanitisePunctuation(char *String) return String; } +enum +{ + INCLUDE_CSS, + INCLUDE_Images, + INCLUDE_JS, +} include_types; + +enum +{ + PAGE_PLAYER = 1 << 0, + PAGE_INDEX = 1 << 1 +} pages; + +void +ConstructURLPrefix(buffer *URLPrefix, int IncludeType, int PageType) +{ + ClaimBuffer(URLPrefix, "URLPrefix", 1024); + if(StringsDiffer(Config.RootURL, "")) + { + URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "%s/", Config.RootURL); + } + else + { + if(Config.Edition == EDITION_PROJECT) + { + if(PageType == PAGE_PLAYER) + { + URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "../"); + } + URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "../"); + } + } + + switch(IncludeType) + { + case INCLUDE_CSS: + if(StringsDiffer(Config.CSSDir, "")) + { + URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "%s/", Config.CSSDir); + } + break; + case INCLUDE_Images: + if(StringsDiffer(Config.ImagesDir, "")) + { + URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "%s/", Config.ImagesDir); + } + break; + case INCLUDE_JS: + if(StringsDiffer(Config.JSDir, "")) + { + URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "%s/", Config.JSDir); + } + break; + } +} + enum { CreditsError_NoHost, @@ -940,29 +1001,14 @@ SearchCredentials(buffer *CreditsMenu, bool *HasCreditsMenu, char *Person, char if(*Credentials[CredentialIndex].SupportIcon && *Credentials[CredentialIndex].SupportURL) { - char URLPrefix[1024] = { 0 }; - char *Ptr = URLPrefix; - if(StringsDiffer(Config.RootURL, "")) - { - Ptr += CopyString(Ptr, "%s/", Config.RootURL); - } - else - { - if(Config.Edition == EDITION_PROJECT) - { - Ptr += CopyString(Ptr, "../"); - } - } - if(StringsDiffer(Config.ImagesDir, "")) - { - CopyString(Ptr, "%s/", Config.ImagesDir); - } - + buffer URLPrefix; + ConstructURLPrefix(&URLPrefix, INCLUDE_Images, PAGE_INDEX); CopyStringToBuffer(CreditsMenu, "
\n", Credentials[CredentialIndex].SupportURL, - URLPrefix, + URLPrefix.Location, Credentials[CredentialIndex].SupportIcon); + DeclaimBuffer(&URLPrefix); } CopyStringToBuffer(CreditsMenu, @@ -1684,12 +1730,6 @@ DepartComment(buffer *Template) } } -enum -{ - PAGE_PLAYER = 1 << 0, - PAGE_INDEX = 1 << 1 -} pages; - int ValidateTemplate(buffer *Errors, template **Template, int PageType) { @@ -2609,31 +2649,16 @@ AppendedIdentifier: " };\n" " \n"); - char URLPrefix[1024] = { 0 }; - char *Ptr = URLPrefix; - if(StringsDiffer(Config.RootURL, "")) - { - Ptr += CopyString(Ptr, "%s/", Config.RootURL); - } - else - { - if(Config.Edition == EDITION_PROJECT) - { - Ptr += CopyString(Ptr, "../"); - } - } - if(StringsDiffer(Config.ImagesDir, "")) - { - CopyString(Ptr, "%s/", Config.ImagesDir); - } - + buffer URLPrefix; + ConstructURLPrefix(&URLPrefix, INCLUDE_Images, PAGE_INDEX); CopyStringToBuffer(&FilterMenu, "
\n" " \n" "
\n" "
Filter mode:
\n" "
\n", - URLPrefix); + URLPrefix.Location); + DeclaimBuffer(&URLPrefix); if(Topics.Count > 0) { @@ -2977,24 +3002,8 @@ AppendedIdentifier: // TODO(matt): Maybe do something about indentation levels - char URLPrefix[1024] = { 0 }; - char *Ptr = URLPrefix; - if(StringsDiffer(Config.RootURL, "")) - { - Ptr += CopyString(Ptr, "%s/", Config.RootURL); - } - else - { - if(Config.Edition == EDITION_PROJECT) - { - Ptr += CopyString(Ptr, "../"); - } - } - if(StringsDiffer(Config.CSSDir, "")) - { - CopyString(Ptr, "%s/", Config.CSSDir); - } - + buffer URLPrefix; + ConstructURLPrefix(&URLPrefix, INCLUDE_CSS, PAGE_INDEX); CopyStringToBuffer(&CollationBuffers->IncludesIndex, "\n" " \n" @@ -3003,24 +3012,16 @@ AppendedIdentifier: "\n" " \n" " \n", - URLPrefix, - URLPrefix, StringsDiffer(Config.Theme, "") ? Config.Theme : HMML.metadata.project, - URLPrefix, + URLPrefix.Location, + URLPrefix.Location, StringsDiffer(Config.Theme, "") ? Config.Theme : HMML.metadata.project, + URLPrefix.Location, CINERA_APP_VERSION.Major, CINERA_APP_VERSION.Minor, CINERA_APP_VERSION.Patch); + DeclaimBuffer(&URLPrefix); - if(Config.Edition == EDITION_PROJECT) - { - if(!StringsDiffer(Config.RootURL, "")) - { - char Temp[1027]; - CopyString(Temp, "../%s", URLPrefix); - CopyString(URLPrefix, Temp); - } - } - + ConstructURLPrefix(&URLPrefix, INCLUDE_CSS, PAGE_PLAYER); CopyStringToBuffer(&CollationBuffers->IncludesPlayer, "\n" " \n" @@ -3028,13 +3029,14 @@ AppendedIdentifier: "\n" " \n" " \n", - URLPrefix, - URLPrefix, StringsDiffer(Config.Theme, "") ? Config.Theme : HMML.metadata.project, - URLPrefix, + URLPrefix.Location, + URLPrefix.Location, StringsDiffer(Config.Theme, "") ? Config.Theme : HMML.metadata.project, + URLPrefix.Location, CINERA_APP_VERSION.Major, CINERA_APP_VERSION.Minor, CINERA_APP_VERSION.Patch); + DeclaimBuffer(&URLPrefix); if(Topics.Count || Media.Count) { @@ -3061,30 +3063,15 @@ AppendedIdentifier: CopyStringToBuffer(&CollationBuffers->IncludesPlayer, "\">\n\n"); } - Ptr = URLPrefix; - if(StringsDiffer(Config.RootURL, "")) - { - Ptr += StringLength(Config.RootURL) + 1; - } - else - { - if(Config.Edition == EDITION_PROJECT) - { - Ptr += StringLength("../"); - } - } - if(StringsDiffer(Config.JSDir, "")) - { - CopyString(Ptr, "%s/", Config.JSDir); - } - + ConstructURLPrefix(&URLPrefix, INCLUDE_JS, PAGE_PLAYER); CopyStringToBuffer(&CollationBuffers->IncludesPlayer, " \n", - URLPrefix); + URLPrefix.Location); CopyStringToBuffer(&CollationBuffers->ScriptPlayer, " \n", - URLPrefix); + URLPrefix.Location); + DeclaimBuffer(&URLPrefix); if(HasFilterMenu) { @@ -3764,31 +3751,23 @@ IndexToBuffer(buffers *CollationBuffers) StringsDiffer(Config.Theme, "") ? Config.Theme : Config.ProjectID, StringsDiffer(Config.Theme, "") ? Config.Theme : Config.ProjectID); - char URLPrefix[1024] = { 0 }; - char *Ptr = URLPrefix; - if(StringsDiffer(Config.RootURL, "")) - { - Ptr += CopyString(Ptr, "%s/", Config.RootURL); - } - else - { - Ptr += CopyString(Ptr, "../"); - } - if(StringsDiffer(Config.JSDir, "")) - { - Ptr += CopyString(Ptr, "%s/", Config.JSDir); - } + buffer URLPrefix; + ClaimBuffer(&URLPrefix, "URLPrefix", 1024); + ConstructURLPrefix(&URLPrefix, INCLUDE_JS, PAGE_INDEX); - char Script[512 + StringLength(URLPrefix) + (StringLength(Config.ProjectID) * 2)]; + char Script[512 + StringLength(URLPrefix.Location) + (StringLength(Config.ProjectID) * 2)]; CopyString(Script, " \n" " \n" " \n", Config.ProjectID, StringsDiffer(Config.Theme, "") ? Config.Theme : Config.ProjectID, - URLPrefix); + StringsDiffer(Config.URLPrefix, "") ? Config.URLPrefix : Config.ProjectID, + URLPrefix.Location); + DeclaimBuffer(&URLPrefix); int EntryLength = 32 + StringLength(ProjectInfo[ProjectIndex].Unit) + 16 + 256; @@ -3822,16 +3801,34 @@ IndexToBuffer(buffers *CollationBuffers) CopyStringNoFormatT(Title, Index.File.Buffer.Ptr, '\n'); Title[StringLength(Title) - 1] = '\0'; + char BaseFilename[255]; + if(StringsDiffer(Config.URLPrefix, "")) + { + char *Ptr = This.BaseFilename + StringLength(Config.ProjectID); + CopyString(BaseFilename, "%s%s", Config.URLPrefix, Ptr); + } + else + { + CopyString(BaseFilename, "%s", This.BaseFilename); + } + if(StringsDiffer(ProjectInfo[ProjectIndex].Unit, "")) { CopyStringToBuffer(&CollationBuffers->Index, "
\n" - " %s %s: %s\n" - "
\n", - This.BaseFilename, + " ", BaseFilename); + + char Text[1024]; // NOTE(matt): Surely this will be big enough + CopyString(Text, "%s %s: %s", ProjectInfo[ProjectIndex].Unit, // TODO(matt): Do we need to special-case the various numbering schemes? Number, Title); + + CopyStringToBufferHTMLSafe(&CollationBuffers->Index, Text); + + CopyStringToBuffer(&CollationBuffers->Index, + "\n" + " \n"); } else { @@ -3839,7 +3836,7 @@ IndexToBuffer(buffers *CollationBuffers) "
\n" " %s\n" "
\n", - This.BaseFilename, + BaseFilename, Title); } @@ -3863,7 +3860,15 @@ int GeneratePlayerPage(buffers *CollationBuffers, template *PlayerTemplate, char *BaseFilename) { char OutputDir[256]; - CopyString(OutputDir, "%s/%s", Config.BaseDir, BaseFilename); + if(StringsDiffer(Config.URLPrefix, "")) + { + char *Ptr = BaseFilename + StringLength(Config.ProjectID); + CopyString(OutputDir, "%s/%s%s", Config.BaseDir, Config.URLPrefix, Ptr); + } + else + { + CopyString(OutputDir, "%s/%s", Config.BaseDir, BaseFilename); + } char PlayerPagePath[256]; CopyString(PlayerPagePath, "%s/index.html", OutputDir); @@ -3899,7 +3904,15 @@ DeletePlayerPageFromFilesystem(char *BaseFilename) { // NOTE(matt): Once we have the notion of an output filename format, we'll need to use that here char PlayerDirPath[256]; - CopyString(PlayerDirPath, "%s/%s", Config.BaseDir, BaseFilename); + if(StringsDiffer(Config.URLPrefix, "")) + { + char *Ptr = BaseFilename + StringLength(Config.ProjectID); + CopyString(PlayerDirPath, "%s/%s%s", Config.BaseDir, Config.URLPrefix, Ptr); + } + else + { + CopyString(PlayerDirPath, "%s/%s", Config.BaseDir, BaseFilename); + } DIR *PlayerDir; if((PlayerDir = opendir(PlayerDirPath))) // There is a directory for the Player, which there probably should be if not for manual intervention @@ -4163,7 +4176,8 @@ main(int ArgC, char **Args) .Theme = "", .TemplatePlayerLocation = "template_player.html", .TemplateIndexLocation = "template_index.html", - .UpdateInterval = 4 + .UpdateInterval = 4, + .URLPrefix = "" }; if(getenv("XDG_CACHE_HOME")) @@ -4253,6 +4267,21 @@ main(int ArgC, char **Args) if(StringsDiffer(Config.ProjectID, "")) { Config.Edition = EDITION_PROJECT; + for(int ProjectInfoIndex = 0; ProjectInfoIndex < ArrayCount(ProjectInfo); ++ProjectInfoIndex) + { + if(!StringsDiffer(Config.ProjectID, ProjectInfo[ProjectInfoIndex].ProjectID)) + { + if(StringsDiffer(ProjectInfo[ProjectInfoIndex].Medium, "")) + { + Config.DefaultMedium = ProjectInfo[ProjectInfoIndex].Medium; + } + if(StringsDiffer(ProjectInfo[ProjectInfoIndex].AltURLPrefix, "")) + { + Config.URLPrefix = ProjectInfo[ProjectInfoIndex].AltURLPrefix; + } + break; + } + } } bool ValidDefaultMedium = FALSE; @@ -4405,6 +4434,7 @@ main(int ArgC, char **Args) " ID:\t\t\t\t%s\n" " Input Directory:\t\t%s\n" " Output Base Directory:\t%s\n" + " Player Page URL Prefix:\t%s\n" " Default Medium:\t\t%s\n" " Style / Theme:\t\t%s\n" "\n" @@ -4413,6 +4443,7 @@ main(int ArgC, char **Args) Config.ProjectID, Config.ProjectDir, Config.BaseDir, + StringsDiffer(Config.URLPrefix, "") ? Config.URLPrefix : Config.ProjectID, Config.DefaultMedium, StringsDiffer(Config.Theme, "") ? Config.Theme: Config.ProjectID); diff --git a/cinera/css/cinera.css b/cinera/cinera.css similarity index 100% rename from cinera/css/cinera.css rename to cinera/cinera.css diff --git a/cinera/images/cinera_icon_filter.png b/cinera/cinera_icon_filter.png similarity index 100% rename from cinera/images/cinera_icon_filter.png rename to cinera/cinera_icon_filter.png diff --git a/cinera/js/cinera_player_post.js b/cinera/cinera_player_post.js similarity index 100% rename from cinera/js/cinera_player_post.js rename to cinera/cinera_player_post.js diff --git a/cinera/js/cinera_player_pre.js b/cinera/cinera_player_pre.js similarity index 100% rename from cinera/js/cinera_player_pre.js rename to cinera/cinera_player_pre.js diff --git a/cinera/js/cinera_search.js b/cinera/cinera_search.js similarity index 96% rename from cinera/js/cinera_search.js rename to cinera/cinera_search.js index a66d8ac..a0b97b1 100644 --- a/cinera/js/cinera_search.js +++ b/cinera/cinera_search.js @@ -17,7 +17,7 @@ var rendering = false; var dayContainerPrototype = document.createElement("DIV"); dayContainerPrototype.classList.add("dayContainer"); -dayContainerPrototype.classList.add(projectID); +dayContainerPrototype.classList.add(theme); var dayNamePrototype = document.createElement("SPAN"); dayNamePrototype.classList.add("dayName"); @@ -25,7 +25,7 @@ dayContainerPrototype.appendChild(dayNamePrototype); var markerListPrototype = document.createElement("DIV"); markerListPrototype.classList.add("markerList"); -markerListPrototype.classList.add(projectID); +markerListPrototype.classList.add(theme); dayContainerPrototype.appendChild(markerListPrototype); var markerPrototype = document.createElement("A"); @@ -206,7 +206,12 @@ xhr.addEventListener("load", function() { episode = {}; mode = "none"; } else if (line.startsWith("name:")) { - episode.name = line.slice(6); + if(projectID != outputURLPrefix) { + episode.name = line.slice(6).replace(projectID, outputURLPrefix); + } + else { + episode.name = line.slice(6); + } } else if (line.startsWith("title:")) { episode.title = line.slice(7).replace(/"/g, ""); } else if (line.startsWith("markers")) { @@ -233,7 +238,7 @@ xhr.addEventListener("load", function() { xhr.addEventListener("error", function() { console.error("Failed to load content"); }); -xhr.open("GET", indexLocation); +xhr.open("GET", projectID + ".index"); xhr.setRequestHeader("Content-Type", "text/plain"); xhr.send(); diff --git a/cinera/images/cinera_sprite_patreon.png b/cinera/cinera_sprite_patreon.png similarity index 100% rename from cinera/images/cinera_sprite_patreon.png rename to cinera/cinera_sprite_patreon.png