\n", HMML.metadata.id, HMML.metadata.project);
+
+ int CreditsErrorCode = BuildCredits(Config, &CreditsMenu, &HasCreditsMenu, Config.ImagesDir, HMML.metadata);
+ if(CreditsErrorCode)
+ {
+ switch(CreditsErrorCode)
+ {
+ case CreditsError_NoHost:
+ fprintf(stderr, "%s: Missing \"member\" in the [video] node. Skipping...\n", Filename);
+ goto Cleanup;
+ break;
+ case CreditsError_NoAnnotator:
+ fprintf(stderr, "%s: Missing \"annotator\" in the [video] node. Skipping...\n", Filename);
+ goto Cleanup;
+ break;
+ default:
+ break;
+ }
+ }
+
+#if DEBUG
+ printf("\n\n --- Entering Annotations Loop ---\n\n\n\n");
+#endif
+ for(int AnnotationIndex = 0; AnnotationIndex < HMML.annotation_count; ++AnnotationIndex)
+ {
+#if DEBUG
+ printf("%d\n", AnnotationIndex);
+#endif
+ HMML_Annotation *Anno = HMML.annotations + AnnotationIndex;
+ categories LocalTopics = { 0 };
+ categories LocalMedia = { 0 };
+ bool HasQuote = FALSE;
+ bool HasReference = FALSE;
+
+ quote_info QuoteInfo = { 0 };
+
+ // NOTE(matt): Tree structure of "annotation local" buffer dependencies
+ // Annotation
+ // AnnotationHeader
+ // AnnotationClass
+ // AnnotationData
+ // Text
+ // TopicDots
+
+ ClaimBuffer(MemoryArena, &Annotation, "Annotation", Kilobytes(8));
+ ClaimBuffer(MemoryArena, &AnnotationHeader, "AnnotationHeader", 512);
+ ClaimBuffer(MemoryArena, &AnnotationClass, "AnnotationClass", 256);
+ ClaimBuffer(MemoryArena, &AnnotationData, "AnnotationData", 512);
+ ClaimBuffer(MemoryArena, &Text, "Text", Kilobytes(4));
+ ClaimBuffer(MemoryArena, &TopicDots, "TopicDots", 512);
+
+ CopyStringToBuffer(&AnnotationHeader,
+ "
time));
+
+ CopyStringToBuffer(&AnnotationClass,
+ " class=\"marker");
+
+ if(Anno->author)
+ {
+ if(!HasFilterMenu)
+ {
+ HasFilterMenu = TRUE;
+ }
+ InsertCategory(&Topics, &Media, "authored");
+ CopyStringToBuffer(&AnnotationClass, " authored");
+ hsl_colour AuthorColour;
+ StringToColourHash(&AuthorColour, Anno->author);
+ if(Config.Edition == EDITION_NETWORK)
+ {
+ fprintf(stderr, "%s:%d - TODO(matt): Implement author hoverbox\n", __FILE__, __LINE__);
+ // NOTE(matt): We should get instructions on how to get this info in the config
+ CopyStringToBuffer(&Text,
+ "
%s ",
+ Anno->author,
+ AuthorColour.Hue, AuthorColour.Saturation, AuthorColour.Lightness,
+ AuthorColour.Hue, AuthorColour.Saturation,
+ Anno->author);
+ }
+ else
+ {
+ CopyStringToBuffer(&Text,
+ "
%s ",
+ AuthorColour.Hue, AuthorColour.Saturation, AuthorColour.Lightness,
+ AuthorColour.Hue, AuthorColour.Saturation,
+ Anno->author);
+ }
+
+ }
+
+ char *InPtr = Anno->text;
+
+ int MarkerIndex = 0, RefIndex = 0;
+ while(*InPtr || RefIndex < Anno->reference_count)
+ {
+ if(MarkerIndex < Anno->marker_count &&
+ InPtr - Anno->text == Anno->markers[MarkerIndex].offset)
+ {
+ char *Readable = Anno->markers[MarkerIndex].parameter
+ ? Anno->markers[MarkerIndex].parameter
+ : Anno->markers[MarkerIndex].marker;
+ if(Anno->markers[MarkerIndex].type == HMML_MEMBER)
+ {
+ hsl_colour MemberColour;
+ StringToColourHash(&MemberColour, Anno->markers[MarkerIndex].marker);
+ if(Config.Edition == EDITION_NETWORK)
+ {
+ fprintf(stderr, "%s:%d - TODO(matt): Implement member hoverbox\n", __FILE__, __LINE__);
+ // NOTE(matt): We should get instructions on how to get this info in the config
+ CopyStringToBuffer(&Text,
+ "
%.*s",
+ Anno->markers[MarkerIndex].marker,
+ MemberColour.Hue, MemberColour.Saturation, MemberColour.Lightness,
+ MemberColour.Hue, MemberColour.Saturation,
+ StringLength(Readable), InPtr);
+ }
+ else
+ {
+ CopyStringToBuffer(&Text,
+ "
%.*s",
+ MemberColour.Hue, MemberColour.Saturation, MemberColour.Lightness,
+ MemberColour.Hue, MemberColour.Saturation,
+ StringLength(Readable), InPtr);
+ }
+
+ InPtr += StringLength(Readable);
+ ++MarkerIndex;
+ }
+ else if(Anno->markers[MarkerIndex].type == HMML_PROJECT)
+ {
+ hsl_colour ProjectColour;
+ StringToColourHash(&ProjectColour, Anno->markers[MarkerIndex].marker);
+ if(Config.Edition == EDITION_NETWORK)
+ {
+ fprintf(stderr, "%s:%d - TODO(matt): Implement project hoverbox\n", __FILE__, __LINE__);
+ // NOTE(matt): We should get instructions on how to get this info in the config
+ CopyStringToBuffer(&Text,
+ "
%s",
+ Anno->markers[MarkerIndex].marker,
+ ProjectColour.Hue, ProjectColour.Saturation, ProjectColour.Lightness,
+ ProjectColour.Hue, ProjectColour.Saturation,
+ Readable);
+ }
+ else
+ {
+ CopyStringToBuffer(&Text,
+ "
%s",
+ ProjectColour.Hue, ProjectColour.Saturation, ProjectColour.Lightness,
+ ProjectColour.Hue, ProjectColour.Saturation,
+ Readable);
+ }
+ InPtr += StringLength(Readable);
+ ++MarkerIndex;
+ }
+ else if(Anno->markers[MarkerIndex].type == HMML_CATEGORY)
+ {
+ GenerateTopicColours(Anno->markers[MarkerIndex].marker, Config.CSSDir);
+ if(!HasFilterMenu)
+ {
+ HasFilterMenu = TRUE;
+ }
+ InsertCategory(&Topics, &Media, Anno->markers[MarkerIndex].marker); // Global
+ InsertCategory(&LocalTopics, &LocalMedia, Anno->markers[MarkerIndex].marker); // Local
+ }
+ }
+
+ while(RefIndex < Anno->reference_count &&
+ InPtr - Anno->text == Anno->references[RefIndex].offset)
+ {
+ HMML_Reference *CurrentRef = Anno->references + RefIndex;
+ if(!HasReferenceMenu)
+ {
+ CopyStringToBuffer(&ReferenceMenu,
+ " \n"
+ "
\n");
+ CopyBuffer(&CollationBuffers->Menus, &ReferenceMenu);
+ }
+
+ if(HasFilterMenu)
+ {
+ CopyStringToBuffer(&FilterState,
+ " var filterState = {\n");
+ for(int i = 0; i < Topics.Count; ++i)
+ {
+ CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n",
+ Topics.Category[i].Marker, "topic");
+ }
+ for(int i = 0; i < Media.Count; ++i)
+ {
+ CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n",
+ Media.Category[i].Marker, "medium");
+ }
+ CopyStringToBuffer(&FilterState,
+ " };\n");
+
+ if(Config.Edition == EDITION_PROJECT)
+ {
+ CopyStringToBuffer(&FilterMenu,
+ " ");
+
+ // TODO(matt): Maybe do something about indentation levels
+ // TODO(matt): We may need to do some actual logic here to figure out
+ // where the style paths are in relation to us, rather than assuming them
+ // to be one directory up the tree
+ if(Config.Edition == EDITION_PROJECT)
+ {
+ CopyStringToBuffer(&CollationBuffers->IncludesIndex,
+ "
\n"
+ "
\n"
+ "
\n",
+ Config.CSSDir,
+ Config.CSSDir,
+ HMML.metadata.project,
+ Config.CSSDir);
+
+ CopyStringToBuffer(&CollationBuffers->IncludesPlayer,
+ "
\n"
+ "
\n"
+ "
\n",
+ Config.CSSDir,
+ Config.CSSDir,
+ HMML.metadata.project,
+ Config.CSSDir);
+ }
+ else
+ {
+ CopyStringToBuffer(&CollationBuffers->IncludesPlayer,
+ "
\n"
+ "
\n"
+ "
\n",
+ Config.CSSDir,
+ Config.CSSDir,
+ HMML.metadata.project,
+ Config.CSSDir);
+ }
+
+ CopyStringToBuffer(&CollationBuffers->IncludesPlayer,
+ "\n"
+ "
\n"
+ "
\n");
+
+ if(Topics.Count || Media.Count)
+ {
+ CopyStringToBuffer(&CollationBuffers->IncludesPlayer,
+ "
0)
+ {
+ for(int i = 0; i < Topics.Count; ++i)
+ {
+ CopyStringToBuffer(&CollationBuffers->IncludesPlayer, "%s, ", Topics.Category[i].Marker);
+ }
+ }
+
+ if(Media.Count > 0)
+ {
+ for(int i = 0; i < Media.Count; ++i)
+ {
+ CopyStringToBuffer(&CollationBuffers->IncludesPlayer, "%s, ", Media.Category[i].WrittenText);
+ }
+ }
+
+ CollationBuffers->IncludesPlayer.Ptr -= 2;
+ CopyStringToBuffer(&CollationBuffers->IncludesPlayer, "\">\n\n");
+ }
+
+ if(Config.Edition == EDITION_PROJECT)
+ {
+ CopyStringToBuffer(&CollationBuffers->IncludesPlayer,
+ " \n",
+ Config.JSDir);
+ }
+ else
+ {
+ CopyStringToBuffer(&CollationBuffers->IncludesPlayer,
+ " \n",
+ Config.JSDir);
+ }
+
+ CopyStringToBuffer(&CollationBuffers->Script,
+ " ");
+
+ // NOTE(matt): Tree structure of "global" buffer dependencies
+ // FilterState
+ // CreditsMenu
+ // FilterMedia
+ // FilterTopics
+ // FilterMenu
+ // ReferenceMenu
+ // QuoteMenu
+
+Cleanup:
+ DeclaimBuffer(MemoryArena, &FilterState);
+
+ DeclaimBuffer(MemoryArena, &CreditsMenu);
+ DeclaimBuffer(MemoryArena, &FilterMedia);
+ DeclaimBuffer(MemoryArena, &FilterTopics);
+ DeclaimBuffer(MemoryArena, &FilterMenu);
+ DeclaimBuffer(MemoryArena, &ReferenceMenu);
+ DeclaimBuffer(MemoryArena, &QuoteMenu);
+ }
+ else
+ {
+ fprintf(stderr, "%s:%d: %s\n", Filename, HMML.error.line, HMML.error.message);
+ }
+ hmml_free(&HMML);
+ return 0;
+}
+
+void
+BuffersToHTML(buffer *MemoryArena, buffers CollationBuffers, buffer Template, config Config, char *OutputPath)
+{
+ buffer Master;
+ ClaimBuffer(MemoryArena, &Master, "Master", Kilobytes(512));
+#if DEBUG
+ printf("\n\n --- Buffer Collation ---\n\n\n\n");
+#endif
+
+ if(Config.Mode == MODE_INTEGRATE)
+ {
+ buffer Output;
+ Output.Size = Template.Size + Master.Size;
+ Output.ID = "Output";
+ if(!(Output.Location = malloc(Output.Size)))
+ {
+ // TODO(matt): Error code
+ //perror(Args[0]); free(Template.Location); hmml_free(&HMML); free(MemoryArena.Location); return 1;
+ }
+ Output.Ptr = Output.Location;
+
+ char *IncludesTag = "__CINERA_INCLUDES__";
+ char *TitleTag = "__CINERA_TITLE__";
+ char *MenusTag = "__CINERA_MENUS__";
+ char *PlayerTag = "__CINERA_PLAYER__";
+ char *ScriptTag = "__CINERA_SCRIPT__";
+
+ while(Template.Ptr - Template.Location < Template.Size)
+ {
+ if(*Template.Ptr == '!' && (Template.Ptr > Template.Location && !StringsDifferT("", Template.Ptr, 0))
+ {
+ Template.Ptr += StringLength("-->");
+ break;
+ }
+ ++Template.Ptr;
+ }
+ break;
+ }
+
+ else if(!(StringsDifferT(TitleTag, Template.Ptr, 0)))
+ {
+ Output.Ptr = CommentStart;
+ CopyStringToBuffer(&Output, CollationBuffers.Title);
+ while(Template.Ptr - Template.Location < Template.Size)
+ {
+ if(!StringsDifferT("-->", Template.Ptr, 0))
+ {
+ Template.Ptr += StringLength("-->");
+ break;
+ }
+ ++Template.Ptr;
+ }
+ break;
+ }
+ else if(!(StringsDifferT(MenusTag, Template.Ptr, 0)))
+ {
+ Output.Ptr = CommentStart;
+ CopyBuffer(&Output, &CollationBuffers.Menus);
+ while(Template.Ptr - Template.Location < Template.Size)
+ {
+ if(!StringsDifferT("-->", Template.Ptr, 0))
+ {
+ Template.Ptr += StringLength("-->");
+ break;
+ }
+ ++Template.Ptr;
+ }
+ break;
+ }
+ else if(!(StringsDifferT(PlayerTag, Template.Ptr, 0)))
+ {
+ Output.Ptr = CommentStart;
+ CopyBuffer(&Output, &CollationBuffers.Player);
+ while(Template.Ptr - Template.Location < Template.Size)
+ {
+ if(!StringsDifferT("-->", Template.Ptr, 0))
+ {
+ Template.Ptr += StringLength("-->");
+ break;
+ }
+ ++Template.Ptr;
+ }
+ break;
+ }
+ else if(!(StringsDifferT(ScriptTag, Template.Ptr, 0)))
+ {
+ Output.Ptr = CommentStart;
+ CopyBuffer(&Output, &CollationBuffers.Script);
+ while(Template.Ptr - Template.Location < Template.Size)
+ {
+ if(!StringsDifferT("-->", Template.Ptr, 0))
+ {
+ Template.Ptr += StringLength("-->");
+ break;
+ }
+ ++Template.Ptr;
+ }
+ break;
+ }
+ else if(!StringsDifferT("-->", Template.Ptr, 0))
+ {
+ break;
+ }
+ *Output.Ptr++ = *Template.Ptr++;
+ }
+ }
+ else
+ {
+ *Output.Ptr++ = *Template.Ptr++;
+ }
+ }
+
+ FILE *OutFile;
+ if(!(OutFile = fopen(Config.Edition == EDITION_PROJECT ? OutputPath : Config.OutIntegratedLocation, "w")))
+ {
+ // TODO(matt): Return code
+ //perror(Config.OutIntegratedLocation); free(Template.Location); free(Output.Location); hmml_free(&HMML); free(MemoryArena.Location); return 1;
+ }
+ fwrite(Output.Location, Output.Ptr - Output.Location, 1, OutFile);
+ fclose(OutFile);
+
+ free(Output.Location);
+ }
+ else
+ {
+ // NOTE(matt): Perform the normal collation into Master, and write-out to out.html
+ CopyStringToBuffer(&Master,
+ "\n"
+ " \n");
+
+ //NOTE(matt): Here is where we do all our CopyBuffer() calls
+ CopyBuffer(&Master, &CollationBuffers.IncludesPlayer);
+ CopyStringToBuffer(&Master,
+ "\n"
+ " \n"
+ " \n");
+ CopyBuffer(&Master, &CollationBuffers.Menus);
+ CopyStringToBuffer(&Master, "\n");
+ CopyBuffer(&Master, &CollationBuffers.Player);
+ CopyStringToBuffer(&Master, "\n");
+ CopyBuffer(&Master, &CollationBuffers.Script);
+ CopyStringToBuffer(&Master, "\n");
+ //
+
+ CopyStringToBuffer(&Master,
+ " \n"
+ "\n");
+
+ FILE *OutFile;
+ if(!(OutFile = fopen(Config.Edition == EDITION_PROJECT ? OutputPath : Config.OutLocation, "w")))
+ {
+ // TODO(matt): Error code
+ //perror(OutLocation); hmml_free(&HMML); free(MemoryArena.Location); return 1;
+ }
+ fwrite(Master.Location, Master.Ptr - Master.Location, 1, OutFile);
+ fclose(OutFile);
+ }
+
+ DeclaimBuffer(MemoryArena, &Master);
+}
+
+int
+BuildIndex(buffer *MemoryArena, buffers *CollationBuffers, config Config, char *BaseFilename, char *Title)
+{
+ char IndexPath[255];
+ CopyString(IndexPath, "%s/index", Config.CacheDir);
+ FILE *IndexFile;
+ if(!(IndexFile = fopen(IndexPath, "a+")))
+ {
+ perror(IndexPath);
+ // TODO(matt): Actual error code
+ return 1;
+ }
+
+ buffer Index;
+ fseek(IndexFile, 0, SEEK_END);
+ Index.Size = ftell(IndexFile);
+ fseek(IndexFile, 0, SEEK_SET);
+
+ if(!(Index.Location = malloc(Index.Size)))
+ {
+ perror("BuildIndex");
+ }
+ Index.Ptr = Index.Location;
+ fread(Index.Location, Index.Size, 1, IndexFile);
+
+ bool Found = FALSE;
+
+ int EntryCount = 0;
+ while(Index.Ptr - Index.Location < Index.Size)
+ {
+ char IndexedFile[32];
+ char *Ptr = IndexedFile;
+ Index.Ptr += CopyStringNoFormatT(Ptr, Index.Ptr, ',');
+ if(!StringsDiffer(IndexedFile, BaseFilename))
+ {
+ Found = TRUE;
+ break;
+ }
+ else
+ {
+ while(Index.Ptr - Index.Location < Index.Size && *Index.Ptr != '\n')
+ {
+ ++Index.Ptr;
+ }
+ ++Index.Ptr;
+ ++EntryCount;
+ }
+ }
+
+ if(Found == FALSE)
+ {
+ ++EntryCount;
+ // TODO(matt): Write the EntryCount into the index
+ fprintf(IndexFile, "%s,%s\n", BaseFilename, Title);
+ {
+ char IndexPagePath[255];
+ CopyString(IndexPagePath, "%s/index.html", Config.BaseDir);
+ CollationBuffers->Index.Ptr = CollationBuffers->Index.Location;
+ CopyStringToBuffer(&CollationBuffers->Index, "
\n");
+ Index.Ptr = Index.Location;
+ while(Index.Ptr - Index.Location < Index.Size)
+ {
+ char IndexedFile[32];
+ char *Ptr = IndexedFile;
+ Index.Ptr += CopyStringNoFormatT(Ptr, Index.Ptr, ',') + 1;
+
+ char Title[255];
+ Ptr = Title;
+ Index.Ptr += CopyStringNoFormatT(Ptr, Index.Ptr, '\n') + 1;
+
+ CopyStringToBuffer(&CollationBuffers->Index,
+" - \n"
+" %s\n"
+"
\n",
+IndexedFile, Title);
+
+ }
+ CopyStringToBuffer(&CollationBuffers->Index, "
\n");
+
+ if(Config.Mode == MODE_INTEGRATE)
+ {
+ }
+ else
+ {
+ }
+
+ buffer Master;
+ ClaimBuffer(MemoryArena, &Master, "Master", Kilobytes(16));
+ CopyStringToBuffer(&Master,
+ "\n"
+ " \n");
+ CopyBuffer(&Master, &CollationBuffers->IncludesIndex);
+
+ CopyStringToBuffer(&Master,
+ "\n"
+ " \n"
+ " \n");
+ CopyBuffer(&Master, &CollationBuffers->Index);
+ CopyStringToBuffer(&Master,
+ "\n"
+ " \n"
+ "\n");
+
+ FILE *ContentsPage;
+ if(!(ContentsPage = fopen(IndexPagePath, "w")))
+ {
+ perror(IndexPagePath);
+ }
+ fwrite(Master.Location, Master.Ptr - Master.Location, 1, ContentsPage);
+ fclose(ContentsPage);
+
+ DeclaimBuffer(MemoryArena, &Master);
+ }
+ }
+
+ fclose(IndexFile);
+ FreeBuffer(&Index);
+ return 0;
}
int
main(int ArgC, char **Args)
{
// TODO(matt): Read all defaults from the config
- char *DefaultBaseOutputDir = ".";
- char *BaseOutputDir = DefaultBaseOutputDir;
+ config DefaultConfig = {
+ .BaseDir = ".",
+ .CSSDir = ".",
+ .Edition = EDITION_SINGLE,
+ .ImagesDir = ".",
+ .JSDir = ".",
+ .DefaultMedium = "programming",
+ .Mode = getenv("CINERA_MODE") ? MODE_INTEGRATE : MODE_BARE,
+ .OutLocation = "out.html",
+ .OutIntegratedLocation = "out_integrated.html",
+ .ForceIntegration = FALSE,
+ .ProjectDir = ".",
+ .TemplateLocation = "template.html"
+ };
- char *DefaultCSSDir = ".";
- char *CSSDir = DefaultCSSDir;
-
- char *DefaultImagesDir = ".";
- char *ImagesDir = DefaultImagesDir;
-
- char *DefaultJSDir = ".";
- char *JSDir = DefaultJSDir;
-
- char *DefaultDefaultMedium = "programming";
- char *DefaultMedium = DefaultDefaultMedium;
-
- bool HasTemplate = FALSE;
- char *DefaultTemplateLocation = "template.html";
- char *TemplateLocation = DefaultTemplateLocation;
- HasTemplate = TRUE;
-
- char *DefaultOutLocation = "out.html";
- char *OutLocation = DefaultOutLocation;
-
- char *DefaultOutIntegratedLocation = "out_integrated.html";
- char *OutIntegratedLocation = DefaultOutIntegratedLocation;
-
- char *DefaultProjectDir = ".";
- char *ProjectDir = DefaultProjectDir;
-
- char *CINERA_MODE = getenv("CINERA_MODE");
-
- bool DefaultForceIntegration = FALSE;
- bool ForceIntegration = DefaultForceIntegration;
-
- char CacheDir[255] = { 0 };
if(getenv("XDG_CACHE_HOME"))
{
- CopyString(CacheDir, "%s/cinera", getenv("XDG_CACHE_HOME"));
+ CopyString(DefaultConfig.CacheDir, "%s/cinera", getenv("XDG_CACHE_HOME"));
}
else
{
- CopyString(CacheDir, "%s/.cache/cinera", getenv("HOME"));
+ CopyString(DefaultConfig.CacheDir, "%s/.cache/cinera", getenv("HOME"));
}
+ config Config = DefaultConfig;
+
if(ArgC < 2)
{
- PrintUsage(Args[0], DefaultBaseOutputDir, DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultProjectDir, DefaultTemplateLocation);
+ PrintUsage(Args[0], DefaultConfig);
return 1;
}
@@ -1530,48 +3087,48 @@ main(int ArgC, char **Args)
switch(CommandLineArg)
{
case 'b':
- BaseOutputDir = optarg;
+ Config.BaseDir = optarg;
break;
case 'c':
- CSSDir = optarg;
+ Config.CSSDir = optarg;
break;
case 'f':
- ForceIntegration = TRUE;
+ Config.ForceIntegration = TRUE;
break;
case 'i':
- ImagesDir = optarg;
+ Config.ImagesDir = optarg;
break;
case 'j':
- JSDir = optarg;
+ Config.JSDir = optarg;
break;
case 'm':
- DefaultMedium = optarg;
+ Config.DefaultMedium = optarg;
break;
case 'o':
- OutLocation = optarg;
- OutIntegratedLocation = optarg;
+ Config.OutLocation = optarg;
+ Config.OutIntegratedLocation = optarg;
break;
case 'p':
- ProjectDir = optarg;
+ Config.ProjectDir = optarg;
break;
case 't':
- TemplateLocation = optarg;
- CINERA_MODE="INTEGRATE";
+ Config.TemplateLocation = optarg;
+ Config.Mode = MODE_INTEGRATE;
break;
//case 'c':
// Override config path, once we even have a default!
case 'h':
default:
- PrintUsage(Args[0], DefaultBaseOutputDir, DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultProjectDir, DefaultTemplateLocation);
+ PrintUsage(Args[0], DefaultConfig);
return 1;
}
}
- if(StringsDiffer(BaseOutputDir, ".") || StringsDiffer(ProjectDir, "."))
+ if(StringsDiffer(Config.BaseDir, ".") || StringsDiffer(Config.ProjectDir, "."))
{
- if(StringsDiffer(BaseOutputDir, ".") && StringsDiffer(ProjectDir, "."))
+ if(StringsDiffer(Config.BaseDir, ".") && StringsDiffer(Config.ProjectDir, "."))
{
- EDITION = EDITION_PROJECT;
+ Config.Edition = EDITION_PROJECT;
}
else
{
@@ -1580,56 +3137,15 @@ main(int ArgC, char **Args)
}
}
- DIR *ProjectDirHandle;
- if(!(ProjectDirHandle = opendir(ProjectDir)))
+ if(Config.CSSDir[StringLength(Config.CSSDir) - 1] == '/')
{
- perror(Args[0]);
- }
-
- struct dirent *ProjectFiles;
- char Filenames[255][255]; // TODO(matt): Figure out how to allow an arbitrary number of filenames here
- int FileIndex = 0;
- while((ProjectFiles = readdir(ProjectDirHandle)))
- {
- // TODO(matt):
- //
- // Test the ProjectFiles->d_name against ".hmml" and, if the filename ends in that string, then stuff that filename into an array
- char *Ptr = ProjectFiles->d_name;
- Ptr += (StringLength(ProjectFiles->d_name) - StringLength(".hmml"));
- if(!(StringsDiffer(Ptr, ".hmml")))
- {
- CopyString(Filenames[FileIndex], ProjectFiles->d_name);
- ++FileIndex;
- }
- }
- closedir(ProjectDirHandle);
- for(int i = 0; i < ArrayCount(Filenames); ++i)
- {
- if(StringsDiffer(Filenames[i], ""))
- {
- printf("%s\n", Filenames[i]);
- }
- }
- return 1;
-
- if((EDITION == EDITION_SINGLE && optind == ArgC) ||
- // TODO(matt): Test against the number of .hmml files in the project directory
- (EDITION == EDITION_PROJECT && 1))
- {
- fprintf(stderr, "%s: requires at least one input .hmml file\n", Args[0]);
- PrintUsage(Args[0], DefaultBaseOutputDir, DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultProjectDir, DefaultTemplateLocation);
- return 1;
- }
-
- if(CSSDir[StringLength(CSSDir) - 1] == '/')
- {
- CSSDir[StringLength(CSSDir) - 1] = '\0';
+ Config.CSSDir[StringLength(Config.CSSDir) - 1] = '\0';
}
bool ValidDefaultMedium = FALSE;
for(int i = 0; i < ArrayCount(CategoryMedium); ++i)
{
- if(!StringsDiffer(DefaultMedium, CategoryMedium[i].Medium))
+ if(!StringsDiffer(Config.DefaultMedium, CategoryMedium[i].Medium))
{
ValidDefaultMedium = TRUE;
break;
@@ -1637,202 +3153,31 @@ main(int ArgC, char **Args)
}
if(!ValidDefaultMedium)
{
- fprintf(stderr, "Specified default medium \"%s\" not available. Valid media are:\n", DefaultMedium);
+ fprintf(stderr, "Specified default medium \"%s\" not available. Valid media are:\n", Config.DefaultMedium);
for(int i = 0; i < ArrayCount(CategoryMedium); ++i)
{
fprintf(stderr, " %s\n", CategoryMedium[i].Medium);
}
- fprintf(stderr, "To have \"%s\" added to the list, contact matt@handmadedev.org\n", DefaultMedium);
+ fprintf(stderr, "To have \"%s\" added to the list, contact matt@handmadedev.org\n", Config.DefaultMedium);
return 1;
}
- if(ImagesDir[StringLength(ImagesDir) - 1] == '/')
+ if(Config.ImagesDir[StringLength(Config.ImagesDir) - 1] == '/')
{
- ImagesDir[StringLength(ImagesDir) - 1] = '\0';
+ Config.ImagesDir[StringLength(Config.ImagesDir) - 1] = '\0';
}
- if(JSDir[StringLength(JSDir) - 1] == '/')
+ if(Config.JSDir[StringLength(Config.JSDir) - 1] == '/')
{
- JSDir[StringLength(JSDir) - 1] = '\0';
+ Config.JSDir[StringLength(Config.JSDir) - 1] = '\0';
}
- buffer Template;
- Template.ID = "Template";
- if(HasTemplate)
- {
- if(CINERA_MODE && !StringsDiffer(CINERA_MODE, "INTEGRATE"))
- {
- // TODO(matt): Put the Errors in the MemoryArena
- buffer Errors;
- Errors.ID = "Errors";
- Errors.Size = Kilobytes(1);
- if(!(Errors.Location = malloc(Errors.Size)))
- {
- perror(Args[0]); return 1;
- }
- Errors.Ptr = Errors.Location;
- bool HaveErrors = FALSE;
-
- FILE *TemplateFile;
- if(!(TemplateFile = fopen(TemplateLocation, "r")))
- {
- perror(Args[0]); return 1;
- }
-
- fseek(TemplateFile, 0, SEEK_END);
- Template.Size = ftell(TemplateFile);
- fseek(TemplateFile, 0, SEEK_SET);
- if(!(Template.Location = malloc(Template.Size)))
- {
- perror(Args[0]); return 1;
- }
- Template.Ptr = Template.Location;
- fread(Template.Location, Template.Size, 1, TemplateFile);
- fclose(TemplateFile);
-
- char *IncludesTag = "__CINERA_INCLUDES__";
- char *TitleTag = "__CINERA_TITLE__";
- char *MenusTag = "__CINERA_MENUS__";
- char *PlayerTag = "__CINERA_PLAYER__";
- char *ScriptTag = "__CINERA_SCRIPT__";
-
- bool FoundIncludes = FALSE;
- bool FoundMenus = FALSE;
- bool FoundPlayer = FALSE;
- bool FoundScript = FALSE;
-
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(*Template.Ptr == '!' && (Template.Ptr > Template.Location && !StringsDifferT(" tag\n");
- HaveErrors = TRUE;
- }
- FoundIncludes = TRUE;
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- Template.Ptr += StringLength("-->");
- break;
- }
- ++Template.Ptr;
- }
- break;
- }
-
- else if(!(StringsDifferT(TitleTag, Template.Ptr, 0)))
- {
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- Template.Ptr += StringLength("-->");
- break;
- }
- ++Template.Ptr;
- }
- break;
- }
- else if(!(StringsDifferT(MenusTag, Template.Ptr, 0)))
- {
- if(!ForceIntegration && FoundMenus == TRUE)
- {
- CopyStringToBuffer(&Errors, "Template contains more than one tag\n");
- HaveErrors = TRUE;
- }
- FoundMenus = TRUE;
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- Template.Ptr += StringLength("-->");
- break;
- }
- ++Template.Ptr;
- }
- break;
- }
- else if(!(StringsDifferT(PlayerTag, Template.Ptr, 0)))
- {
- if(!ForceIntegration && FoundPlayer == TRUE)
- {
- CopyStringToBuffer(&Errors, "Template contains more than one tag\n");
- HaveErrors = TRUE;
- }
- FoundPlayer = TRUE;
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- Template.Ptr += StringLength("-->");
- break;
- }
- ++Template.Ptr;
- }
- break;
- }
- else if(!(StringsDifferT(ScriptTag, Template.Ptr, 0)))
- {
- if(!ForceIntegration && FoundPlayer == FALSE)
- {
- CopyStringToBuffer(&Errors, " must come after \n");
- HaveErrors = TRUE;
- }
- if(!ForceIntegration && FoundScript == TRUE)
- {
- CopyStringToBuffer(&Errors, "Template contains more than one tag\n");
- HaveErrors = TRUE;
- }
- FoundScript = TRUE;
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- Template.Ptr += StringLength("-->");
- break;
- }
- ++Template.Ptr;
- }
- break;
- }
- else if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- break;
- }
- ++Template.Ptr;
- }
- }
- else
- {
- ++Template.Ptr;
- }
- }
-
- if(!HaveErrors && FoundIncludes && FoundMenus && FoundPlayer && FoundScript)
- {
- Template.Ptr = Template.Location;
- free(Errors.Location);
- }
- else
- {
- if(!ForceIntegration)
- {
- if(!FoundIncludes){ CopyStringToBuffer(&Errors, "Template must include one tag\n"); };
- if(!FoundMenus){ CopyStringToBuffer(&Errors, "Template must include one tag\n"); };
- if(!FoundPlayer){ CopyStringToBuffer(&Errors, "Template must include one tag\n"); };
- if(!FoundScript){ CopyStringToBuffer(&Errors, "Template must include one tag\n"); };
- fprintf(stderr, "%s", Errors.Location);
- free(Template.Location); free(Errors.Location); return 1;
- }
- }
- }
- }
+ // NOTE(matt): Templating
+ //
+ // Config will contain paths of multiple templates
+ // App is running all the time, and picking up changes to the config as we go
+ // If we find a new template, we first of all validate it
+ // In our case here, we just want to straight up validate a template if Config.Mode == MODE_INTEGRATE
+ // And, in that same state, we gotta keep a Template buffer around
// NOTE(matt): Init MemoryArena
buffer MemoryArena;
@@ -1840,1501 +3185,126 @@ main(int ArgC, char **Args)
if(!(MemoryArena.Location = calloc(MemoryArena.Size, 1)))
{
perror(Args[0]);
- free(Template.Location);
+ //free(Template.Location);
return 1;
}
- int ClaimedMemory = 0;
+ MemoryArena.Ptr = MemoryArena.Location;
// NOTE(matt): Setup buffers and ptrs
- char *InPtr;
-
-#if CONFIG
- buffer Config;
-#endif
+ // TODO(matt)
+ //char *InPtr;
// NOTE(matt): Tree structure of buffer dependencies
- // Master
- // Includes
+ // IncludesPlayer
// Menus
- // QuoteMenu
- // ReferenceMenu
- // FilterMenu
- // FilterTopics
- // FilterMedia
- // CreditsMenu
// Player
- // Annotation
- // AnnotationHeader
- // AnnotationClass
- // AnnotationData
- // Text
- // Category
// Script
- // FilterState
- buffer Master;
- buffer Includes;
+ // TODO(matt)
+#if 1
+ buffers CollationBuffers;
+ ClaimBuffer(&MemoryArena, &CollationBuffers.IncludesPlayer, "IncludesPlayer", Kilobytes(1));
+ ClaimBuffer(&MemoryArena, &CollationBuffers.Menus, "Menus", Kilobytes(24));
+ ClaimBuffer(&MemoryArena, &CollationBuffers.Player, "Player", Kilobytes(256));
+ ClaimBuffer(&MemoryArena, &CollationBuffers.Script, "Script", Kilobytes(8));
- buffer Menus;
- buffer QuoteMenu;
- buffer ReferenceMenu;
- buffer FilterMenu;
- buffer FilterTopics;
- buffer FilterMedia;
- buffer CreditsMenu;
+ ClaimBuffer(&MemoryArena, &CollationBuffers.IncludesIndex, "IncludesIndex", Kilobytes(1));
+ ClaimBuffer(&MemoryArena, &CollationBuffers.Index, "Index", Kilobytes(8));
+ *CollationBuffers.Title = '\0';
- buffer Player;
- buffer Annotation;
- buffer AnnotationHeader;
- buffer AnnotationClass;
- buffer AnnotationData;
- buffer Text;
- buffer TopicDots;
+ buffer Template;
+ Template.ID = "Template";
- buffer Script;
- buffer FilterState;
-
- //HMMLToBuffers(&CollationBuffers, Filename);
-
- for(int FileIndex = optind; FileIndex < ArgC; ++FileIndex)
+ if(Config.Mode == MODE_INTEGRATE)
{
- // NOTE(matt): Start of HMMLToBuffers()
- FILE *InFile;
- if(!(InFile = fopen(Args[FileIndex], "r")))
+ ValidateTemplate(&Template, Config);
+ }
+
+ // NOTE(matt)
+ //
+ // Single Edition == Loop over Args[FileIndex]
+ // Project Edition == Loop over Config.ProjectDir
+ //
+ // Integrating or not
+
+ if(Config.Edition == EDITION_PROJECT)
+ {
+ DIR *ProjectDirHandle;
+ if(!(ProjectDirHandle = opendir(Config.ProjectDir)))
{
- perror(Args[FileIndex]);
- free(MemoryArena.Location);
- free(Template.Location);
+ perror(Config.ProjectDir);
+ // TODO(matt):
+ // Cleanup
+ }
+
+ struct dirent *ProjectFiles;
+ int FileIndex = 0;
+ while((ProjectFiles = readdir(ProjectDirHandle)))
+ {
+ // TODO(matt):
+ char *Ptr = ProjectFiles->d_name;
+ Ptr += (StringLength(ProjectFiles->d_name) - StringLength(".hmml"));
+ if(!(StringsDiffer(Ptr, ".hmml")))
+ {
+ *Ptr = '\0';
+ char BaseFilename[255];
+ CopyString(BaseFilename, ProjectFiles->d_name);
+ *Ptr = '.';
+
+ char OutputDir[255];
+ CopyString(OutputDir, "%s/%s", Config.BaseDir, BaseFilename);
+ // TODO(matt): Check
+ char OutputPath[255];
+ CopyString(OutputPath, "%s/index.html", OutputDir);
+ DIR *OutputDirectoryHandle;
+ if(!(OutputDirectoryHandle = opendir(OutputDir)))
+ {
+ MakeDir(OutputDir);
+ }
+ closedir(OutputDirectoryHandle);
+
+ HMMLToBuffers(&MemoryArena, &CollationBuffers, Config, ProjectFiles->d_name);
+ BuildIndex(&MemoryArena, &CollationBuffers, Config, BaseFilename, CollationBuffers.Title);
+ ++FileIndex;
+ BuffersToHTML(&MemoryArena, CollationBuffers, Template, Config, OutputPath);
+ }
+ }
+ closedir(ProjectDirHandle);
+
+ if(Config.Edition == EDITION_SINGLE && optind == ArgC)
+ {
+ fprintf(stderr, "%s: requires at least one input .hmml file\n", Args[0]);
+ PrintUsage(Args[0], DefaultConfig);
return 1;
}
-
- HMML_Output HMML = hmml_parse_file(InFile);
- fclose(InFile);
-
-#if CONFIG
- ClaimBuffer(MemoryArena, &ClaimedMemory, &Config, "Config", Kilobytes(1));
-#endif
-
- if(HMML.well_formed)
- {
-#if DEBUG
- printf(
- "================================================================================\n"
- "%s\n"
- "================================================================================\n",
- Args[FileIndex]);
-#endif
- // NOTE(matt): Tree structure of "global" buffer dependencies
- // Master
- // Includes
- // Menus
- // QuoteMenu
- // ReferenceMenu
- // FilterMenu
- // FilterTopics
- // FilterMedia
- // CreditsMenu
- // Player
- // Script
- // FilterState
-
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &Master, "Master", Kilobytes(512));
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &Includes, "Includes", Kilobytes(1));
-
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &Menus, "Menus", Kilobytes(24));
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &QuoteMenu, "QuoteMenu", Kilobytes(16));
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &ReferenceMenu, "ReferenceMenu", Kilobytes(16));
- 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, &Player, "Player", Kilobytes(256));
-
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &Script, "Script", Kilobytes(8));
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &FilterState, "FilterState", Kilobytes(4));
-
- ref_info ReferencesArray[200] = { 0 };
- categories Topics = { 0 };
- categories Media = { 0 };
-
- bool HasQuoteMenu = FALSE;
- bool HasReferenceMenu = FALSE;
- bool HasFilterMenu = FALSE;
- bool HasCreditsMenu = FALSE;
-
- int QuoteIdentifier = 0x3b1;
- int RefIdentifier = 1;
- int UniqueRefs = 0;
-
- CopyStringToBuffer(&Menus,
- "
\n"
- "
", HMML.metadata.project);
- CopyStringToBufferHTMLSafe(&Menus, HMML.metadata.title);
- CopyStringToBuffer(&Menus, "\n"
- "
⚠ Click here to regain focus ⚠\n");
-
- CopyStringToBuffer(&Player,
- "
\n"
- "
\n"
- "
\n", HMML.metadata.id, HMML.metadata.project);
-
- int CreditsErrorCode = BuildCredits(&CreditsMenu, &HasCreditsMenu, ImagesDir, HMML.metadata);
- if(CreditsErrorCode)
- {
- switch(CreditsErrorCode)
- {
- case CreditsError_NoHost:
- fprintf(stderr, "%s: Missing \"member\" in the [video] node. Skipping...\n", Args[FileIndex]);
-goto Cleanup;
- break;
- case CreditsError_NoAnnotator:
- fprintf(stderr, "%s: Missing \"annotator\" in the [video] node. Skipping...\n", Args[FileIndex]);
-goto Cleanup;
- break;
- default:
- break;
- }
- }
-
-#if DEBUG
- printf(" --- Entering Annotations Loop ---\n");
-#endif
-
- for(int AnnotationIndex = 0; AnnotationIndex < HMML.annotation_count; ++AnnotationIndex)
- {
-#if DEBUG
- printf("%d\n", AnnotationIndex);
-#endif
- HMML_Annotation *Anno = HMML.annotations + AnnotationIndex;
- categories LocalTopics = { 0 };
- categories LocalMedia = { 0 };
- bool HasQuote = FALSE;
- bool HasReference = FALSE;
-
- quote_info QuoteInfo = { 0 };
-
- // NOTE(matt): Tree structure of "annotation local" buffer dependencies
- // Annotation
- // AnnotationHeader
- // AnnotationClass
- // AnnotationData
- // Text
- // TopicDots
-
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &Annotation, "Annotation", Kilobytes(8));
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationHeader, "AnnotationHeader", 512);
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationClass, "AnnotationClass", 256);
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationData, "AnnotationData", 512);
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &Text, "Text", Kilobytes(4));
- ClaimBuffer(&MemoryArena, &ClaimedMemory, &TopicDots, "TopicDots", 512);
-
- CopyStringToBuffer(&AnnotationHeader,
- "
time));
-
- CopyStringToBuffer(&AnnotationClass,
- " class=\"marker");
-
- if(Anno->author)
- {
- if(!HasFilterMenu)
- {
- HasFilterMenu = TRUE;
- }
- InsertCategory(&Topics, &Media, "authored");
- CopyStringToBuffer(&AnnotationClass, " authored");
- hsl_colour AuthorColour;
- StringToColourHash(&AuthorColour, Anno->author);
- if(EDITION == EDITION_NETWORK)
- {
- fprintf(stderr, "%s:%d - TODO(matt): Implement author hoverbox\n", __FILE__, __LINE__);
- // NOTE(matt): We should get instructions on how to get this info in the config
- CopyStringToBuffer(&Text,
- "
%s ",
- Anno->author,
- AuthorColour.Hue, AuthorColour.Saturation, AuthorColour.Lightness,
- AuthorColour.Hue, AuthorColour.Saturation,
- Anno->author);
- }
- else
- {
- CopyStringToBuffer(&Text,
- "
%s ",
- AuthorColour.Hue, AuthorColour.Saturation, AuthorColour.Lightness,
- AuthorColour.Hue, AuthorColour.Saturation,
- Anno->author);
- }
-
- }
-
- InPtr = Anno->text;
-
- int MarkerIndex = 0, RefIndex = 0;
- while(*InPtr || RefIndex < Anno->reference_count)
- {
- if(MarkerIndex < Anno->marker_count &&
- InPtr - Anno->text == Anno->markers[MarkerIndex].offset)
- {
- char *Readable = Anno->markers[MarkerIndex].parameter
- ? Anno->markers[MarkerIndex].parameter
- : Anno->markers[MarkerIndex].marker;
- if(Anno->markers[MarkerIndex].type == HMML_MEMBER)
- {
- hsl_colour MemberColour;
- StringToColourHash(&MemberColour, Anno->markers[MarkerIndex].marker);
- if(EDITION == EDITION_NETWORK)
- {
- fprintf(stderr, "%s:%d - TODO(matt): Implement member hoverbox\n", __FILE__, __LINE__);
- // NOTE(matt): We should get instructions on how to get this info in the config
- CopyStringToBuffer(&Text,
- "
%.*s",
- Anno->markers[MarkerIndex].marker,
- MemberColour.Hue, MemberColour.Saturation, MemberColour.Lightness,
- MemberColour.Hue, MemberColour.Saturation,
- StringLength(Readable), InPtr);
- }
- else
- {
- CopyStringToBuffer(&Text,
- "
%.*s",
- MemberColour.Hue, MemberColour.Saturation, MemberColour.Lightness,
- MemberColour.Hue, MemberColour.Saturation,
- StringLength(Readable), InPtr);
- }
-
- InPtr += StringLength(Readable);
- ++MarkerIndex;
- }
- else if(Anno->markers[MarkerIndex].type == HMML_PROJECT)
- {
- hsl_colour ProjectColour;
- StringToColourHash(&ProjectColour, Anno->markers[MarkerIndex].marker);
- if(EDITION == EDITION_NETWORK)
- {
- fprintf(stderr, "%s:%d - TODO(matt): Implement project hoverbox\n", __FILE__, __LINE__);
- // NOTE(matt): We should get instructions on how to get this info in the config
- CopyStringToBuffer(&Text,
- "
%s",
- Anno->markers[MarkerIndex].marker,
- ProjectColour.Hue, ProjectColour.Saturation, ProjectColour.Lightness,
- ProjectColour.Hue, ProjectColour.Saturation,
- Readable);
- }
- else
- {
- CopyStringToBuffer(&Text,
- "
%s",
- ProjectColour.Hue, ProjectColour.Saturation, ProjectColour.Lightness,
- ProjectColour.Hue, ProjectColour.Saturation,
- Readable);
- }
- InPtr += StringLength(Readable);
- ++MarkerIndex;
- }
- else if(Anno->markers[MarkerIndex].type == HMML_CATEGORY)
- {
- GenerateTopicColours(Anno->markers[MarkerIndex].marker, CSSDir);
- if(!HasFilterMenu)
- {
- HasFilterMenu = TRUE;
- }
- InsertCategory(&Topics, &Media, Anno->markers[MarkerIndex].marker); // Global
- InsertCategory(&LocalTopics, &LocalMedia, Anno->markers[MarkerIndex].marker); // Local
- }
- }
-
- while(RefIndex < Anno->reference_count &&
- InPtr - Anno->text == Anno->references[RefIndex].offset)
- {
- HMML_Reference *CurrentRef = Anno->references + RefIndex;
- if(!HasReferenceMenu)
- {
- CopyStringToBuffer(&ReferenceMenu,
- " \n"
- "
\n");
- CopyBuffer(&Menus, &ReferenceMenu);
- }
-
- if(HasFilterMenu)
- {
- CopyStringToBuffer(&FilterState,
- " var filterState = {\n");
- for(int i = 0; i < Topics.Count; ++i)
- {
- CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n",
- Topics.Category[i].Marker, "topic");
- }
- for(int i = 0; i < Media.Count; ++i)
- {
- CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n",
- Media.Category[i].Marker, "medium");
- }
- CopyStringToBuffer(&FilterState,
- " };\n");
-
- CopyStringToBuffer(&FilterMenu,
- " \n");
-
- CopyBuffer(&Menus, &FilterMenu);
-
- }
-
- if(HasCreditsMenu)
- {
- CopyBuffer(&Menus, &CreditsMenu);
- }
-
-#if CONFIG
- // TODO(matt): Here is where I test ParseConfig
- ParseConfig(&Config, HMML.metadata.annotator);
-#endif
- CopyStringToBuffer(&Menus,
- "
\n"
- "
?\n"
- "
\n"
- "
?Keyboard Navigation
\n"
- "\n"
- /* NOTE(matt) */
- "
Global Keys
\n"
- "
W,
A,
P /
S,
D,
N Jump to previous / next marker\n");
-
- if(HasFilterMenu)
- {
- CopyStringToBuffer(&Menus,
- "
z Toggle filter mode V Revert filter to original state\n");
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
z Toggle filter mode V Revert filter to original state\n");
- }
-
- CopyStringToBuffer(&Menus,
- "\n"
- "
Menu toggling
\n");
-
- if(HasQuoteMenu)
- {
- CopyStringToBuffer(&Menus,
- "
q Quotes\n");
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
q Quotes\n");
- }
-
- if(HasReferenceMenu)
- {
- CopyStringToBuffer(&Menus,
- "
r References\n");
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
r References\n");
- }
-
- if(HasFilterMenu)
- {
- CopyStringToBuffer(&Menus,
- "
f Filter\n");
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
f Filter\n");
- }
-
- if(HasCreditsMenu)
- {
- CopyStringToBuffer(&Menus,
- "
c Credits\n");
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
c Credits\n");
- }
-
- CopyStringToBuffer(&Menus,
- "\n"
- "
Movement
\n"
- "
\n"
- "
\n"
- "
\n"
- " a\n"
- "
\n"
- "
\n"
- " w
\n"
- " s\n"
- "
\n"
- "
\n"
- " d\n"
- "
\n"
- "
\n"
- "
\n"
- " h\n"
- " j\n"
- " k\n"
- " l\n"
- "
\n"
- "
\n"
- "
\n"
- " ←\n"
- "
\n"
- "
\n"
- " ↑
\n"
- " ↓\n"
- "
\n"
- "
\n"
- " →\n"
- "
\n"
- "
\n"
- "
\n"
- "
\n");
-
- // NOTE(matt);
-
- if(HasQuoteMenu)
- {
- CopyStringToBuffer(&Menus,
- "
Quotes ");
- if(HasReferenceMenu)
- {
- CopyStringToBuffer(&Menus, "and References Menus
\n");
- }
- else
- {
- CopyStringToBuffer(&Menus, "
and References Menus\n");
- }
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
Quotes");
- if(HasReferenceMenu)
- {
- CopyStringToBuffer(&Menus, " and References Menus
\n");
- }
- else
- {
- CopyStringToBuffer(&Menus, " and References Menus\n");
- }
- }
-
- if(HasQuoteMenu || HasReferenceMenu)
- {
- CopyStringToBuffer(&Menus,
- "
Enter Jump to timecode\n");
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
Enter Jump to timecode\n");
- }
-
- CopyStringToBuffer(&Menus, "\n");
-
- if(HasQuoteMenu)
- {
- CopyStringToBuffer(&Menus,
- "
Quotes");
- if(HasReferenceMenu)
- {
- CopyStringToBuffer(&Menus, ", References ");
- if(HasCreditsMenu)
- {
- CopyStringToBuffer(&Menus, "and Credits Menus
");
- }
- else
- {
- CopyStringToBuffer(&Menus, "
and Credits Menus");
- }
- }
- else
- {
- CopyStringToBuffer(&Menus, "
, References ");
- if(HasCreditsMenu)
- {
- CopyStringToBuffer(&Menus, "and Credits Menus");
- }
- else
- {
- CopyStringToBuffer(&Menus, "and Credits Menus");
- }
- }
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
Quotes");
- if(HasReferenceMenu)
- {
- CopyStringToBuffer(&Menus, ", References ");
- if(HasCreditsMenu)
- {
- CopyStringToBuffer(&Menus, "and Credits Menus
");
- }
- else
- {
- CopyStringToBuffer(&Menus, "
and Credits Menus");
- }
- }
- else
- {
- CopyStringToBuffer(&Menus, ", References ");
- if(HasCreditsMenu)
- {
- CopyStringToBuffer(&Menus, "and Credits Menus");
- }
- else
- {
- CopyStringToBuffer(&Menus, "and Credits Menus");
- }
- }
- }
-
- CopyStringToBuffer(&Menus, "\n");
-
- if(HasQuoteMenu || HasReferenceMenu || HasCreditsMenu)
- {
- CopyStringToBuffer(&Menus,
- "
o Open URL (in new tab)\n");
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
o Open URL (in new tab)\n");
- }
-
- CopyStringToBuffer(&Menus,
- "\n");
-
- if(HasFilterMenu)
- {
- CopyStringToBuffer(&Menus,
- "
Filter Menu
\n"
- "
x,
Space Toggle category and focus next\n"
- "
X,
ShiftSpace Toggle category and focus previous\n"
- "
v Invert topics / media as per focus\n");
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
Filter Menu
\n"
- "
x,
Space Toggle category and focus next\n"
- "
X,
ShiftSpace Toggle category and focus previous\n"
- "
v Invert topics / media as per focus\n");
- }
-
- CopyStringToBuffer(&Menus, "\n");
-
- if(HasCreditsMenu)
- {
- CopyStringToBuffer(&Menus,
- "
Credits Menu
\n"
- "
Enter Open URL (in new tab)\n");
- }
- else
- {
- CopyStringToBuffer(&Menus,
- "
Credits Menu
\n"
- "
Enter Open URL (in new tab)\n");
- }
-
- CopyStringToBuffer(&Menus,
- "
\n"
- "
\n"
-
- "
");
-
- CopyStringToBuffer(&Player,
- "
\n"
- "
");
-
- // TODO(matt): Maybe do something about indentation levels
- CopyStringToBuffer(&Includes,
- "
\n"
- "
\n"
- "
\n"
- "\n"
- "
\n"
- "
\n",
- CSSDir,
- CSSDir,
- HMML.metadata.project,
- CSSDir);
-
- if(Topics.Count || Media.Count)
- {
- CopyStringToBuffer(&Includes,
- "
0)
- {
- for(int i = 0; i < Topics.Count; ++i)
- {
- CopyStringToBuffer(&Includes, "%s, ", Topics.Category[i].Marker);
- }
- }
-
- if(Media.Count > 0)
- {
- for(int i = 0; i < Media.Count; ++i)
- {
- CopyStringToBuffer(&Includes, "%s, ", Media.Category[i].WrittenText);
- }
- }
-
- Includes.Ptr -= 2;
- CopyStringToBuffer(&Includes, "\">\n\n");
- }
-
- CopyStringToBuffer(&Includes,
- " \n",
- JSDir);
-
- CopyStringToBuffer(&Script,
- " ");
-
- // NOTE(matt): Don't include this in HMMLToBuffers()
-#if DEBUG
- printf("Buffer Collation\n\n");
-#endif
-
- if(CINERA_MODE && !StringsDiffer(CINERA_MODE, "INTEGRATE"))
- {
- buffer Output;
- Output.Size = Template.Size + Master.Size;
- Output.ID = "Output";
- if(!(Output.Location = malloc(Output.Size)))
- {
- perror(Args[0]); free(Template.Location); hmml_free(&HMML); free(MemoryArena.Location); return 1;
- }
- Output.Ptr = Output.Location;
-
- char *IncludesTag = "__CINERA_INCLUDES__";
- char *TitleTag = "__CINERA_TITLE__";
- char *MenusTag = "__CINERA_MENUS__";
- char *PlayerTag = "__CINERA_PLAYER__";
- char *ScriptTag = "__CINERA_SCRIPT__";
-
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(*Template.Ptr == '!' && (Template.Ptr > Template.Location && !StringsDifferT("", Template.Ptr, 0))
- {
- Template.Ptr += StringLength("-->");
- break;
- }
- ++Template.Ptr;
- }
- break;
- }
-
- else if(!(StringsDifferT(TitleTag, Template.Ptr, 0)))
- {
- Output.Ptr = CommentStart;
- CopyStringToBuffer(&Output, HMML.metadata.title);
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- Template.Ptr += StringLength("-->");
- break;
- }
- ++Template.Ptr;
- }
- break;
- }
- else if(!(StringsDifferT(MenusTag, Template.Ptr, 0)))
- {
- Output.Ptr = CommentStart;
- CopyBuffer(&Output, &Menus);
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- Template.Ptr += StringLength("-->");
- break;
- }
- ++Template.Ptr;
- }
- break;
- }
- else if(!(StringsDifferT(PlayerTag, Template.Ptr, 0)))
- {
- Output.Ptr = CommentStart;
- CopyBuffer(&Output, &Player);
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- Template.Ptr += StringLength("-->");
- break;
- }
- ++Template.Ptr;
- }
- break;
- }
- else if(!(StringsDifferT(ScriptTag, Template.Ptr, 0)))
- {
- Output.Ptr = CommentStart;
- CopyBuffer(&Output, &Script);
- while(Template.Ptr - Template.Location < Template.Size)
- {
- if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- Template.Ptr += StringLength("-->");
- break;
- }
- ++Template.Ptr;
- }
- break;
- }
- else if(!StringsDifferT("-->", Template.Ptr, 0))
- {
- break;
- }
- *Output.Ptr++ = *Template.Ptr++;
- }
- }
- else
- {
- *Output.Ptr++ = *Template.Ptr++;
- }
- }
-
- FILE *OutFile;
- if(!(OutFile = fopen(OutIntegratedLocation, "w")))
- {
- perror(OutIntegratedLocation); free(Template.Location); free(Output.Location); hmml_free(&HMML); free(MemoryArena.Location); return 1;
- }
- fwrite(Output.Location, Output.Ptr - Output.Location, 1, OutFile);
- fclose(OutFile);
-
- free(Template.Location);
- free(Output.Location);
- }
- else
- {
- // NOTE(matt): Perform the normal collation into Master, and write-out to out.html
- CopyStringToBuffer(&Master,
- "\n"
- " \n");
-
- //NOTE(matt): Here is where we do all our CopyBuffer() calls
- CopyBuffer(&Master, &Includes);
- CopyStringToBuffer(&Master,
- "\n"
- " \n"
- " \n");
- CopyBuffer(&Master, &Menus);
- CopyStringToBuffer(&Master, "\n");
- CopyBuffer(&Master, &Player);
- CopyStringToBuffer(&Master, "\n");
- CopyBuffer(&Master, &Script);
- CopyStringToBuffer(&Master, "\n");
- //
-
- CopyStringToBuffer(&Master,
- " \n"
- "\n");
-
- FILE *OutFile;
- if(!(OutFile = fopen(OutLocation, "w")))
- {
- perror(OutLocation); hmml_free(&HMML); free(MemoryArena.Location); return 1;
- }
- fwrite(Master.Location, Master.Ptr - Master.Location, 1, OutFile);
- fclose(OutFile);
- }
-
- // NOTE(matt): Start to include this stuff in HMMLToBuffers()
-
- // NOTE(matt): Tree structure of "global" buffer dependencies
- // FilterState
- // Script
- // Player
- // CreditsMenu
- // FilterMedia
- // FilterTopics
- // FilterMenu
- // ReferenceMenu
- // QuoteMenu
- // Menus
- // Includes
- // Master
-
-Cleanup:
- DeclaimBuffer(&FilterState, &ClaimedMemory);
- DeclaimBuffer(&Script, &ClaimedMemory);
- DeclaimBuffer(&Player, &ClaimedMemory);
-
- DeclaimBuffer(&CreditsMenu, &ClaimedMemory);
- DeclaimBuffer(&FilterMedia, &ClaimedMemory);
- DeclaimBuffer(&FilterTopics, &ClaimedMemory);
- DeclaimBuffer(&FilterMenu, &ClaimedMemory);
- DeclaimBuffer(&ReferenceMenu, &ClaimedMemory);
- DeclaimBuffer(&QuoteMenu, &ClaimedMemory);
- DeclaimBuffer(&Menus, &ClaimedMemory);
-
- DeclaimBuffer(&Includes, &ClaimedMemory);
- DeclaimBuffer(&Master, &ClaimedMemory);
- }
- else
- {
- fprintf(stderr, "%s:%d: %s\n", Args[FileIndex], HMML.error.line, HMML.error.message);
- }
- hmml_free(&HMML);
- // NOTE(matt): End of HMMLToBuffers()
}
+ else
+ {
+ for(int FileIndex = optind; FileIndex < ArgC; ++FileIndex)
+ {
+ HMMLToBuffers(&MemoryArena, &CollationBuffers, Config, Args[FileIndex]);
+ BuffersToHTML(&MemoryArena, CollationBuffers, Template, Config, Args[FileIndex]);
+ }
+ }
+
+ if(Config.Mode == MODE_INTEGRATE)
+ {
+ FreeBuffer(&Template);
+ }
+
+ // TODO(matt): Handle return codes
+#endif
+
+
+ // TODO(matt)
+#if 1
+#endif
+
+ DeclaimBuffer(&MemoryArena, &CollationBuffers.Index);
+ DeclaimBuffer(&MemoryArena, &CollationBuffers.IncludesIndex);
+ DeclaimBuffer(&MemoryArena, &CollationBuffers.Script);
+ DeclaimBuffer(&MemoryArena, &CollationBuffers.Player);
+ DeclaimBuffer(&MemoryArena, &CollationBuffers.Menus);
+ DeclaimBuffer(&MemoryArena, &CollationBuffers.IncludesPlayer);
free(MemoryArena.Location);
}