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