hmml_to_html.c: Handle all ref combinations [#16]

This commit is contained in:
Matt Mascarenhas 2017-04-21 02:25:40 +01:00
parent ba13066d63
commit fbdc26dfd5
1 changed files with 105 additions and 83 deletions

View File

@ -50,33 +50,6 @@ ClaimBuffer(char *MemoryArena, int *ClaimedMemory, buffer *Buffer, int Size)
Buffer->Ptr = Buffer->Location; Buffer->Ptr = Buffer->Location;
} }
#if 0
//TODO(matt): Rewrite me
ref_info
ParseRef(HMML_Reference RefInput)
{
ref_info Info;
if(RefInput.author)
{
Info.Source = RefInput.author;
Info.RefTitle = RefInput.title;
return Info;
}
else if(RefInput.page)
{
Info.Source = RefInput.site;
Info.RefTitle = RefInput.page;
return Info;
}
else
{
Info.Source = "";
Info.RefTitle = RefInput.site;
return Info;
}
}
#endif
int int
TimecodeToSeconds(char *Timecode) TimecodeToSeconds(char *Timecode)
{ {
@ -152,9 +125,9 @@ StringsDiffer(char *A, char *B)
typedef struct typedef struct
{ {
int Hue; unsigned int Hue:16;
int Saturation; unsigned int Saturation:8;
int Lightness; unsigned int Lightness:8;
} hsl_colour; } hsl_colour;
hsl_colour hsl_colour
@ -246,44 +219,78 @@ char *CategoryMedium[] =
"run", "run",
}; };
void int
BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMML_Reference Ref, HMML_Annotation Anno) BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMML_Reference Ref, HMML_Annotation Anno)
{ {
if(Ref.isbn) if(Ref.page && Ref.url && Ref.title)
{
CopyString(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyString(ReferencesArray[UniqueRefs].Source, Ref.title);
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.page);
CopyString(ReferencesArray[UniqueRefs].URL, Ref.url);
}
else if(Ref.url && Ref.title)
{
CopyString(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.title);
CopyString(ReferencesArray[UniqueRefs].URL, Ref.url);
}
else if(Ref.site && Ref.page && Ref.url)
{
CopyString(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyString(ReferencesArray[UniqueRefs].Source, Ref.site);
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.page);
CopyString(ReferencesArray[UniqueRefs].URL, Ref.url);
}
else if(Ref.site && Ref.url)
{
CopyString(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.site);
CopyString(ReferencesArray[UniqueRefs].URL, Ref.url);
}
else if(Ref.site && Ref.url && Ref.title)
{
CopyString(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyString(ReferencesArray[UniqueRefs].Source, Ref.site);
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.title);
CopyString(ReferencesArray[UniqueRefs].URL, Ref.url);
}
else if(Ref.url && Ref.title && Ref.author && Ref.publisher && Ref.isbn)
{
CopyString(ReferencesArray[UniqueRefs].ID, Ref.isbn);
CopyString(ReferencesArray[UniqueRefs].Source, "%s (%s)", Ref.author, Ref.publisher);
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.title);
CopyString(ReferencesArray[UniqueRefs].URL, Ref.url);
}
else if(Ref.title && Ref.author && Ref.isbn)
{ {
CopyString(ReferencesArray[UniqueRefs].ID, Ref.isbn); CopyString(ReferencesArray[UniqueRefs].ID, Ref.isbn);
// NOTE(matt): I could probably do with Asserting some of this stuff
CopyString(ReferencesArray[UniqueRefs].Source, Ref.author); CopyString(ReferencesArray[UniqueRefs].Source, Ref.author);
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.title); CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.title);
if(Ref.url) CopyString(ReferencesArray[UniqueRefs].URL, "http://www.isbnsearch.org/isbn/%s", Ref.isbn);
{
CopyString(ReferencesArray[UniqueRefs].URL, Ref.url);
}
else
{
// TODO(matt): Find better ISBN search site?
CopyString(ReferencesArray[UniqueRefs].URL, "http://www.isbnsearch.org/isbn/%s", Ref.isbn);
}
} }
else if(Ref.url) else if(Ref.url && Ref.article && Ref.author)
{ {
CopyString(ReferencesArray[UniqueRefs].ID, Ref.url); // NOTE(matt): Normalise? CopyString(ReferencesArray[UniqueRefs].ID, Ref.url);
if(Ref.page) CopyString(ReferencesArray[UniqueRefs].Source, Ref.author);
{ CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.article);
CopyString(ReferencesArray[UniqueRefs].Source, Ref.site);
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.page);
}
else
{
// NOTE(matt): Empty Source
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.site);
}
CopyString(ReferencesArray[UniqueRefs].URL, Ref.url); CopyString(ReferencesArray[UniqueRefs].URL, Ref.url);
} }
else if(Ref.url && Ref.title && Ref.author)
{
CopyString(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyString(ReferencesArray[UniqueRefs].Source, Ref.author);
CopyString(ReferencesArray[UniqueRefs].RefTitle, Ref.title);
CopyString(ReferencesArray[UniqueRefs].URL, Ref.url);
}
else
{
return 1;
}
CopyString(ReferencesArray[UniqueRefs].Identifier[ReferencesArray[UniqueRefs].IdentifierCount].Timecode, Anno.time); CopyString(ReferencesArray[UniqueRefs].Identifier[ReferencesArray[UniqueRefs].IdentifierCount].Timecode, Anno.time);
ReferencesArray[UniqueRefs].Identifier[ReferencesArray[UniqueRefs].IdentifierCount].Identifier = RefIdentifier; ReferencesArray[UniqueRefs].Identifier[ReferencesArray[UniqueRefs].IdentifierCount].Identifier = RefIdentifier;
return 0;
} }
void void
@ -348,6 +355,7 @@ GenerateTopicColours(buffer *Colour, char *Topic)
if(!strncmp(SanitisePunctuation(Topic), TopicsPtr, StringLength(Topic))) if(!strncmp(SanitisePunctuation(Topic), TopicsPtr, StringLength(Topic)))
{ {
free(TopicsBuffer); free(TopicsBuffer);
fclose(TopicsFile);
return; return;
} }
while(TopicsPtr - TopicsBuffer < TopicsLength && *TopicsPtr != '\n') while(TopicsPtr - TopicsBuffer < TopicsLength && *TopicsPtr != '\n')
@ -409,6 +417,9 @@ main(int ArgC, char **Args)
for(int FileIndex = 1; FileIndex < ArgC; ++FileIndex) for(int FileIndex = 1; FileIndex < ArgC; ++FileIndex)
{ {
// TODO(matt): Maybe look into this further. It works, but there may be
// bugs lurking
ClaimedMemory = 0;
FILE *InFile; FILE *InFile;
if(!(InFile = fopen(Args[FileIndex], "r"))) if(!(InFile = fopen(Args[FileIndex], "r")))
{ {
@ -507,7 +518,6 @@ Readable);
} }
else if(Anno->markers[MarkerIndex].type == HMML_CATEGORY) else if(Anno->markers[MarkerIndex].type == HMML_CATEGORY)
{ {
// TODO(matt): Uncomment
GenerateTopicColours(&Colour, Anno->markers[MarkerIndex].marker); GenerateTopicColours(&Colour, Anno->markers[MarkerIndex].marker);
BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, Anno->markers[MarkerIndex].marker); BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, Anno->markers[MarkerIndex].marker);
} }
@ -527,7 +537,13 @@ Readable);
" <div class=\"mouse_catcher\"></div>\n" " <div class=\"mouse_catcher\"></div>\n"
" <div class=\"refs\">\n"); " <div class=\"refs\">\n");
BuildReference(ReferencesArray, RefIdentifier, UniqueRefs, *CurrentRef, *Anno); if(BuildReference(ReferencesArray, RefIdentifier, UniqueRefs, *CurrentRef, *Anno) == 1)
{
fprintf(stderr, "%s:%d: Cannot process new combination of reference info\n", Args[FileIndex], Anno->line);
hmml_free(&HMML);
free(MemoryArena);
return 1;
}
++ReferencesArray[RefIdentifier - 1].IdentifierCount; ++ReferencesArray[RefIdentifier - 1].IdentifierCount;
++UniqueRefs; ++UniqueRefs;
@ -564,7 +580,13 @@ Readable);
} }
} }
BuildReference(ReferencesArray, RefIdentifier, UniqueRefs, *CurrentRef, *Anno); if(BuildReference(ReferencesArray, RefIdentifier, UniqueRefs, *CurrentRef, *Anno) == 1)
{
fprintf(stderr, "%s:%d: Cannot process new combination of reference info\n", Args[FileIndex], Anno->line);
hmml_free(&HMML);
free(MemoryArena);
return 1;
}
++ReferencesArray[UniqueRefs].IdentifierCount; ++ReferencesArray[UniqueRefs].IdentifierCount;
++UniqueRefs; ++UniqueRefs;
} }
@ -602,7 +624,7 @@ AppendedIdentifier:
} }
else else
{ {
fprintf(stderr, "%s:%d: Reference must have an ISBN or URL", Args[0], Anno->line); fprintf(stderr, "%s:%d: Reference must have an ISBN or URL", Args[FileIndex], Anno->line);
free(MemoryArena); free(MemoryArena);
hmml_free(&HMML); hmml_free(&HMML);
return 1; return 1;
@ -637,7 +659,7 @@ AppendedIdentifier:
if(!HasReference) if(!HasReference)
{ {
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, 32); ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, 128);
CopyStringToBuffer(&AnnotationData, " data-ref=\"&#%d;", QuoteIdentifier); CopyStringToBuffer(&AnnotationData, " data-ref=\"&#%d;", QuoteIdentifier);
} }
else else
@ -674,24 +696,27 @@ Anno->time);
while(MarkerIndex < Anno->marker_count) while(MarkerIndex < Anno->marker_count)
{ {
//TODO(matt): Uncomment
GenerateTopicColours(&Colour, Anno->markers[MarkerIndex].marker); GenerateTopicColours(&Colour, Anno->markers[MarkerIndex].marker);
ClaimedMemory -= Colour.Size;
BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, Anno->markers[MarkerIndex].marker); BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, Anno->markers[MarkerIndex].marker);
} }
CopyStringToBuffer(&AnnotationClass, "\""); CopyStringToBuffer(&AnnotationClass, "\"");
CopyBuffer(&AnnotationHeader, &AnnotationClass); CopyBuffer(&AnnotationHeader, &AnnotationClass);
ClaimedMemory -= AnnotationClass.Size;
if(HasQuote || HasReference) if(HasQuote || HasReference)
{ {
CopyStringToBuffer(&AnnotationData, "\""); CopyStringToBuffer(&AnnotationData, "\"");
CopyBuffer(&AnnotationHeader, &AnnotationData); CopyBuffer(&AnnotationHeader, &AnnotationData);
ClaimedMemory -= AnnotationData.Size;
} }
CopyStringToBuffer(&AnnotationHeader, ">\n"); CopyStringToBuffer(&AnnotationHeader, ">\n");
ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, 1024 * 4); ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, 1024 * 4);
CopyBuffer(&Annotation, &AnnotationHeader); CopyBuffer(&Annotation, &AnnotationHeader);
ClaimedMemory -= AnnotationHeader.Size;
CopyStringToBuffer(&Annotation, CopyStringToBuffer(&Annotation,
" <div class=\"content\"><span class=\"timecode\">%s</span>", " <div class=\"content\"><span class=\"timecode\">%s</span>",
Anno->time); Anno->time);
@ -700,6 +725,7 @@ Anno->time);
{ {
CopyStringToBuffer(&Category, "</span>"); CopyStringToBuffer(&Category, "</span>");
CopyBuffer(&Text, &Category); CopyBuffer(&Text, &Category);
ClaimedMemory -= Category.Size;
} }
*Text.Ptr = '\0'; *Text.Ptr = '\0';
@ -720,6 +746,7 @@ Anno->time);
Anno->time); Anno->time);
CopyBuffer(&Annotation, &Text); CopyBuffer(&Annotation, &Text);
ClaimedMemory -= Text.Size;
CopyStringToBuffer(&Annotation, "</div>\n" CopyStringToBuffer(&Annotation, "</div>\n"
" </div>\n" " </div>\n"
@ -727,11 +754,6 @@ Anno->time);
CopyBuffer(&Player, &Annotation); CopyBuffer(&Player, &Annotation);
ClaimedMemory -= Colour.Size;
ClaimedMemory -= Text.Size;
ClaimedMemory -= AnnotationHeader.Size;
ClaimedMemory -= Category.Size;
ClaimedMemory -= AnnotationClass.Size;
ClaimedMemory -= Annotation.Size; ClaimedMemory -= Annotation.Size;
} }
@ -741,6 +763,7 @@ Anno->time);
" </div>\n" " </div>\n"
" </div>\n"); " </div>\n");
CopyBuffer(&Title, &QuoteMenu); CopyBuffer(&Title, &QuoteMenu);
ClaimedMemory -= QuoteMenu.Size;
} }
if(HasReferenceMenu) if(HasReferenceMenu)
@ -753,8 +776,7 @@ Anno->time);
ReferencesArray[i].ID, ReferencesArray[i].ID,
ReferencesArray[i].URL); ReferencesArray[i].URL);
if(*ReferencesArray[i].Source)
if(ReferencesArray[i].Source)
{ {
CopyStringToBuffer(&ReferenceMenu, CopyStringToBuffer(&ReferenceMenu,
" <div class=\"source\">%s</div>\n" " <div class=\"source\">%s</div>\n"
@ -766,28 +788,28 @@ ReferencesArray[i].RefTitle);
{ {
CopyStringToBuffer(&ReferenceMenu, CopyStringToBuffer(&ReferenceMenu,
" <div class=\"ref_title\">%s</div>\n", " <div class=\"ref_title\">%s</div>\n",
ReferencesArray[i].Source); ReferencesArray[i].RefTitle);
} }
CopyStringToBuffer(&ReferenceMenu, CopyStringToBuffer(&ReferenceMenu,
" </span>\n"); " </span>\n");
// TODO(matt): Fill the div class="ref_indices" with <= 3 span for(int j = 0; j < ReferencesArray[i].IdentifierCount;)
// class="ref_index" and ensure to put these <=3 spans on the same line without
// a space between them
CopyStringToBuffer(&ReferenceMenu,
" <div class=\"ref_indices\">\n ");
for(int j = 0; j < ReferencesArray[i].IdentifierCount; ++j)
{ {
CopyStringToBuffer(&ReferenceMenu, CopyStringToBuffer(&ReferenceMenu,
" <div class=\"ref_indices\">\n ");
for(int k = 0; k < 3 && j < ReferencesArray[i].IdentifierCount; ++k, ++j)
{
CopyStringToBuffer(&ReferenceMenu,
"<span data-timestamp=\"%d\" class=\"timecode\"><span class=\"ref_index\">[%d]</span><span class=\"time\">%s</span></span>", "<span data-timestamp=\"%d\" class=\"timecode\"><span class=\"ref_index\">[%d]</span><span class=\"time\">%s</span></span>",
TimecodeToSeconds(ReferencesArray[i].Identifier[j].Timecode), TimecodeToSeconds(ReferencesArray[i].Identifier[j].Timecode),
ReferencesArray[i].Identifier[j].Identifier, ReferencesArray[i].Identifier[j].Identifier,
ReferencesArray[i].Identifier[j].Timecode); ReferencesArray[i].Identifier[j].Timecode);
}
CopyStringToBuffer(&ReferenceMenu, "\n"
" </div>\n");
} }
CopyStringToBuffer(&ReferenceMenu, "\n" CopyStringToBuffer(&ReferenceMenu,
" </div>\n"
" </a>\n"); " </a>\n");
} }
@ -795,11 +817,13 @@ ReferencesArray[i].Identifier[j].Timecode);
" </div>\n" " </div>\n"
" </div>\n"); " </div>\n");
CopyBuffer(&Title, &ReferenceMenu); CopyBuffer(&Title, &ReferenceMenu);
ClaimedMemory -= ReferenceMenu.Size;
} }
CopyStringToBuffer(&Title, CopyStringToBuffer(&Title,
" <span class=\"annotator_container\">Annotator: <span class=\"annotator\">%s</span></span>\n" " <span class=\"annotator_container\">Annotator: <span class=\"annotator\">%s</span></span>\n"
" </div>\n", HMML.metadata.annotator); " </div>\n",
HMML.metadata.annotator);
CopyStringToBuffer(&Player, CopyStringToBuffer(&Player,
" </div>\n" " </div>\n"
@ -823,7 +847,9 @@ ReferencesArray[i].Identifier[j].Timecode);
//NOTE(matt): Here is where we do all our CopyBuffer() calls //NOTE(matt): Here is where we do all our CopyBuffer() calls
CopyBuffer(&Master, &Title); CopyBuffer(&Master, &Title);
ClaimedMemory -= Title.Size;
CopyBuffer(&Master, &Player); CopyBuffer(&Master, &Player);
ClaimedMemory -= Player.Size;
// //
CopyStringToBuffer(&Master, CopyStringToBuffer(&Master,
@ -914,10 +940,6 @@ ReferencesArray[i].Identifier[j].Timecode);
fwrite(Master.Location, Master.Ptr - Master.Location, 1, OutFile); fwrite(Master.Location, Master.Ptr - Master.Location, 1, OutFile);
fclose(OutFile); fclose(OutFile);
ClaimedMemory -= AnnotationData.Size;
ClaimedMemory -= QuoteMenu.Size;
ClaimedMemory -= ReferenceMenu.Size;
ClaimedMemory -= Title.Size;
ClaimedMemory -= Master.Size; ClaimedMemory -= Master.Size;
} }
else else