hmml_to_html.c: Quote and Ref Menus [#16 #20]

PPiC 063
This commit is contained in:
Matt Mascarenhas 2017-03-29 04:38:12 +01:00
parent b32fd1e066
commit 04f2fcd529
1 changed files with 170 additions and 35 deletions

View File

@ -106,6 +106,7 @@ CopyBuffer(buffer *Src, buffer *Dest)
} }
} }
__attribute__ ((format (printf, 2, 3)))
void void
CopyStringToBuffer(buffer *Dest, char *Format, ...) CopyStringToBuffer(buffer *Dest, char *Format, ...)
{ {
@ -214,15 +215,13 @@ BuildCategories(buffer *AnnotationClass, buffer *Category, int *MarkerIndex, boo
} }
if(*HasCategory == FALSE) if(*HasCategory == FALSE)
{ {
CopyStringToBuffer(Category, "<span class=\"categories\"><div class=\"category %s\"></div>", CopyStringToBuffer(Category, "<span class=\"categories\">");
SanitisePunctuation(Marker));
*HasCategory = TRUE; *HasCategory = TRUE;
} }
else
{
CopyStringToBuffer(Category, "<div class=\"category %s\"></div>", CopyStringToBuffer(Category, "<div class=\"category %s\"></div>",
SanitisePunctuation(Marker)); SanitisePunctuation(Marker));
}
CopyStringToBuffer(AnnotationClass, " cat_%s", CopyStringToBuffer(AnnotationClass, " cat_%s",
SanitisePunctuation(Marker)); SanitisePunctuation(Marker));
++*MarkerIndex; ++*MarkerIndex;
@ -284,6 +283,12 @@ main(int ArgC, char **Args)
ClaimBuffer(MemoryArena, &ClaimedMemory, &Title, 1024 * 16); ClaimBuffer(MemoryArena, &ClaimedMemory, &Title, 1024 * 16);
ClaimBuffer(MemoryArena, &ClaimedMemory, &Player, 1024 * 256); ClaimBuffer(MemoryArena, &ClaimedMemory, &Player, 1024 * 256);
bool HasQuoteMenu = FALSE;
bool HasReferenceMenu = FALSE;
int QuoteIdentifier = 945;
int RefIdentifier = 1;
CopyStringToBuffer(&Title, CopyStringToBuffer(&Title,
" <div class=\"title\">\n" " <div class=\"title\">\n"
" <span class=\"episode_name\">%s</span>\n", HMML.metadata.title); " <span class=\"episode_name\">%s</span>\n", HMML.metadata.title);
@ -295,69 +300,123 @@ main(int ArgC, char **Args)
for(int AnnotationIndex = 0; AnnotationIndex < HMML.annotation_count; ++AnnotationIndex) for(int AnnotationIndex = 0; AnnotationIndex < HMML.annotation_count; ++AnnotationIndex)
{ {
HMML_Annotation *Anno = HMML.annotations + AnnotationIndex;
bool HasCategory = FALSE; bool HasCategory = FALSE;
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationHeader, 256); bool HasQuote = FALSE;
bool HasReference = FALSE;
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationHeader, 512);
ClaimBuffer(MemoryArena, &ClaimedMemory, &Category, 256); ClaimBuffer(MemoryArena, &ClaimedMemory, &Category, 256);
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationClass, 128); ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationClass, 256);
ClaimBuffer(MemoryArena, &ClaimedMemory, &Text, 1024 * 4); ClaimBuffer(MemoryArena, &ClaimedMemory, &Text, 1024 * 4);
CopyStringToBuffer(&AnnotationHeader, CopyStringToBuffer(&AnnotationHeader,
" <div data-timestamp=\"%d\"", " <div data-timestamp=\"%d\"",
TimecodeToSeconds(HMML.annotations[AnnotationIndex].time)); TimecodeToSeconds(Anno->time));
CopyStringToBuffer(&AnnotationClass, CopyStringToBuffer(&AnnotationClass,
" class=\"marker"); " class=\"marker");
if(HMML.annotations[AnnotationIndex].author) if(Anno->author)
{ {
CopyStringToBuffer(&AnnotationClass, " authored"); CopyStringToBuffer(&AnnotationClass, " authored");
CopyStringToBuffer(&Text, CopyStringToBuffer(&Text,
"<span class=\"author\" style=\"color: #%X;\">%s</span> ", "<span class=\"author\" style=\"color: #%X;\">%s</span> ",
StringToColourHash(HMML.annotations[AnnotationIndex].author), StringToColourHash(Anno->author),
HMML.annotations[AnnotationIndex].author); Anno->author);
} }
InPtr = HMML.annotations[AnnotationIndex].text; InPtr = Anno->text;
int MarkerIndex = 0, RefIndex = 0; int MarkerIndex = 0, RefIndex = 0;
while(*InPtr) while(*InPtr || RefIndex < Anno->reference_count)
{ {
if(MarkerIndex < HMML.annotations[AnnotationIndex].marker_count && if(MarkerIndex < Anno->marker_count &&
InPtr - HMML.annotations[AnnotationIndex].text == HMML.annotations[AnnotationIndex].markers[MarkerIndex].offset) InPtr - Anno->text == Anno->markers[MarkerIndex].offset)
{ {
char *Readable = HMML.annotations[AnnotationIndex].markers[MarkerIndex].parameter char *Readable = Anno->markers[MarkerIndex].parameter
? HMML.annotations[AnnotationIndex].markers[MarkerIndex].parameter ? Anno->markers[MarkerIndex].parameter
: HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker; : Anno->markers[MarkerIndex].marker;
if(HMML.annotations[AnnotationIndex].markers[MarkerIndex].type == HMML_MEMBER) if(Anno->markers[MarkerIndex].type == HMML_MEMBER)
{ {
CopyStringToBuffer(&Text, CopyStringToBuffer(&Text,
"<a href=\"https://handmade.network/m/%s\" target=\"blank\" style=\"color: #%X; text-decoration: none\">%.*s</a>", "<a href=\"https://handmade.network/m/%s\" target=\"blank\" style=\"color: #%X; text-decoration: none\">%.*s</a>",
HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker, Anno->markers[MarkerIndex].marker,
StringToColourHash(HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker), StringToColourHash(Anno->markers[MarkerIndex].marker),
StringLength(Readable), InPtr); StringLength(Readable), InPtr);
InPtr += StringLength(Readable); InPtr += StringLength(Readable);
++MarkerIndex; ++MarkerIndex;
} }
else if(HMML.annotations[AnnotationIndex].markers[MarkerIndex].type == HMML_PROJECT) else if(Anno->markers[MarkerIndex].type == HMML_PROJECT)
{ {
CopyStringToBuffer(&Text, CopyStringToBuffer(&Text,
"<a href=\"https://%s.handmade.network/\" target=\"blank\" style=\"color: #%X; text-decoration: none\">%s</a>", "<a href=\"https://%s.handmade.network/\" target=\"blank\" style=\"color: #%X; text-decoration: none\">%s</a>",
HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker, Anno->markers[MarkerIndex].marker,
StringToColourHash(HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker), StringToColourHash(Anno->markers[MarkerIndex].marker),
Readable); Readable);
InPtr += StringLength(Readable); InPtr += StringLength(Readable);
++MarkerIndex; ++MarkerIndex;
} }
else if(HMML.annotations[AnnotationIndex].markers[MarkerIndex].type == HMML_CATEGORY) else if(Anno->markers[MarkerIndex].type == HMML_CATEGORY)
{ {
BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker); BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, Anno->markers[MarkerIndex].marker);
} }
} }
if(RefIndex < HMML.annotations[AnnotationIndex].reference_count && if(RefIndex < Anno->reference_count &&
InPtr - HMML.annotations[AnnotationIndex].text == HMML.annotations[AnnotationIndex].references[RefIndex].offset) InPtr - Anno->text == Anno->references[RefIndex].offset)
{ {
HMML_Reference *CurrentRef = Anno->references + RefIndex;
if(!HasReferenceMenu)
{
ClaimBuffer(MemoryArena, &ClaimedMemory, &ReferenceMenu, 1024 * 16);
CopyStringToBuffer(&ReferenceMenu,
" <div class=\"refs_container\">\n"
" <span>References &#9660;</span>\n"
" <div class=\"mouse_catcher\"></div>\n"
" <div class=\"refs\">\n");
HasReferenceMenu = TRUE;
}
if(!HasReference)
{
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, 128);
CopyStringToBuffer(&AnnotationData, " data-ref=\"%s", CurrentRef->editor);
HasReference = TRUE;
}
else
{
CopyStringToBuffer(&AnnotationData, ",%s", CurrentRef->editor);
}
CopyStringToBuffer(&ReferenceMenu,
" <a data-id=\"%s\" href=\"%s\" target=\"_blank\" class=\"ref\">\n"
" <span class=\"ref_content\">\n"
" <div class=\"source\">%s</div>\n"
" <div class=\"ref_title\">%s</div>\n"
" </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
" <div class=\"ref_indices\">\n"
" <span data-timestamp=\"%d\" class=\"timecode\"><span class=\"ref_index\">[%d]</span><span class=\"time\">%s</span></span>\n"
" </div>\n"
" </a>\n",
CurrentRef->editor,
"http://example.com/",
"Source",
"Title",
TimecodeToSeconds(Anno->time),
RefIdentifier,
Anno->time);
CopyStringToBuffer(&Text, "<sup>%d</sup>", RefIdentifier);
++RefIndex; ++RefIndex;
++RefIdentifier;
} }
if(*InPtr) if(*InPtr)
@ -366,13 +425,70 @@ Readable);
} }
} }
while(MarkerIndex < HMML.annotations[AnnotationIndex].marker_count) if(Anno->is_quote)
{ {
BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker); if(!HasQuoteMenu)
{
ClaimBuffer(MemoryArena, &ClaimedMemory, &QuoteMenu, 1024 * 16);
CopyStringToBuffer(&QuoteMenu,
" <div class=\"refs_container\">\n"
" <span>Quotes &#9660;</span>\n"
" <div class=\"mouse_catcher\"></div>\n"
" <div class=\"refs\">\n");
HasQuoteMenu = TRUE;
}
if(!HasReference)
{
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationData, 32);
CopyStringToBuffer(&AnnotationData, " data-ref=\"&#%d;", QuoteIdentifier);
}
else
{
CopyStringToBuffer(&AnnotationData, ",&#%d;", QuoteIdentifier);
}
HasQuote = TRUE;
CopyStringToBuffer(&QuoteMenu,
" <span data-id=\"&#%d;\" class=\"ref\">\n"
" <span class=\"ref_content\">\n"
" <div class=\"source\">#%d • %s</div>\n"
" <div class=\"ref_title\">%s</div>\n"
" </span>\n"
" <div class=\"ref_indices\">\n"
" <span data-timestamp=\"%d\" class=\"timecode\"><span class=\"ref_index\">[&#%d;]</span><span class=\"time\">%s</span></span>\n"
" </div>\n"
" </span>\n",
QuoteIdentifier,
Anno->quote.id,
"Quote date",
"Quote text",
TimecodeToSeconds(Anno->time),
QuoteIdentifier,
Anno->time);
if(!Anno->text[0])
{
CopyStringToBuffer(&Text, "&#8220;Quote text&#8221;");
}
CopyStringToBuffer(&Text, "<sup>&#%d;</sup>", QuoteIdentifier);
++QuoteIdentifier;
}
while(MarkerIndex < Anno->marker_count)
{
BuildCategories(&AnnotationClass, &Category, &MarkerIndex, &HasCategory, Anno->markers[MarkerIndex].marker);
} }
CopyStringToBuffer(&AnnotationClass, "\""); CopyStringToBuffer(&AnnotationClass, "\"");
CopyBuffer(&AnnotationClass, &AnnotationHeader); CopyBuffer(&AnnotationClass, &AnnotationHeader);
if(HasQuote || HasReference)
{
CopyStringToBuffer(&AnnotationData, "\"");
CopyBuffer(&AnnotationData, &AnnotationHeader);
}
CopyStringToBuffer(&AnnotationHeader, ">\n"); CopyStringToBuffer(&AnnotationHeader, ">\n");
ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, 1024 * 4); ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, 1024 * 4);
@ -380,7 +496,7 @@ Readable);
CopyBuffer(&AnnotationHeader, &Annotation); CopyBuffer(&AnnotationHeader, &Annotation);
CopyStringToBuffer(&Annotation, CopyStringToBuffer(&Annotation,
" <div class=\"content\"><span class=\"timecode\">%s</span>", " <div class=\"content\"><span class=\"timecode\">%s</span>",
HMML.annotations[AnnotationIndex].time); Anno->time);
if(HasCategory) if(HasCategory)
{ {
@ -395,7 +511,7 @@ HMML.annotations[AnnotationIndex].time);
CopyStringToBuffer(&Annotation, "</div>\n" CopyStringToBuffer(&Annotation, "</div>\n"
" <div class=\"progress faded\">\n" " <div class=\"progress faded\">\n"
" <div class=\"content\"><span class=\"timecode\">%s</span>", " <div class=\"content\"><span class=\"timecode\">%s</span>",
HMML.annotations[AnnotationIndex].time); Anno->time);
CopyBuffer(&Text, &Annotation); CopyBuffer(&Text, &Annotation);
@ -403,7 +519,7 @@ HMML.annotations[AnnotationIndex].time);
" </div>\n" " </div>\n"
" <div class=\"progress main\">\n" " <div class=\"progress main\">\n"
" <div class=\"content\"><span class=\"timecode\">%s</span>", " <div class=\"content\"><span class=\"timecode\">%s</span>",
HMML.annotations[AnnotationIndex].time); Anno->time);
CopyBuffer(&Text, &Annotation); CopyBuffer(&Text, &Annotation);
@ -420,6 +536,22 @@ HMML.annotations[AnnotationIndex].time);
ClaimedMemory -= Annotation.Size; ClaimedMemory -= Annotation.Size;
} }
if(HasQuoteMenu)
{
CopyStringToBuffer(&QuoteMenu,
" </div>\n"
" </div>\n");
CopyBuffer(&QuoteMenu, &Title);
}
if(HasReferenceMenu)
{
CopyStringToBuffer(&ReferenceMenu,
" </div>\n"
" </div>\n");
CopyBuffer(&ReferenceMenu, &Title);
}
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);
@ -535,6 +667,9 @@ HMML.annotations[AnnotationIndex].time);
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 -= Title.Size;
ClaimedMemory -= Master.Size; ClaimedMemory -= Master.Size;
} }