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
CopyStringToBuffer(buffer *Dest, char *Format, ...)
{
@ -214,15 +215,13 @@ BuildCategories(buffer *AnnotationClass, buffer *Category, int *MarkerIndex, boo
}
if(*HasCategory == FALSE)
{
CopyStringToBuffer(Category, "<span class=\"categories\"><div class=\"category %s\"></div>",
SanitisePunctuation(Marker));
CopyStringToBuffer(Category, "<span class=\"categories\">");
*HasCategory = TRUE;
}
else
{
CopyStringToBuffer(Category, "<div class=\"category %s\"></div>",
SanitisePunctuation(Marker));
}
CopyStringToBuffer(AnnotationClass, " cat_%s",
SanitisePunctuation(Marker));
++*MarkerIndex;
@ -284,6 +283,12 @@ main(int ArgC, char **Args)
ClaimBuffer(MemoryArena, &ClaimedMemory, &Title, 1024 * 16);
ClaimBuffer(MemoryArena, &ClaimedMemory, &Player, 1024 * 256);
bool HasQuoteMenu = FALSE;
bool HasReferenceMenu = FALSE;
int QuoteIdentifier = 945;
int RefIdentifier = 1;
CopyStringToBuffer(&Title,
" <div class=\"title\">\n"
" <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)
{
HMML_Annotation *Anno = HMML.annotations + AnnotationIndex;
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, &AnnotationClass, 128);
ClaimBuffer(MemoryArena, &ClaimedMemory, &AnnotationClass, 256);
ClaimBuffer(MemoryArena, &ClaimedMemory, &Text, 1024 * 4);
CopyStringToBuffer(&AnnotationHeader,
" <div data-timestamp=\"%d\"",
TimecodeToSeconds(HMML.annotations[AnnotationIndex].time));
TimecodeToSeconds(Anno->time));
CopyStringToBuffer(&AnnotationClass,
" class=\"marker");
if(HMML.annotations[AnnotationIndex].author)
if(Anno->author)
{
CopyStringToBuffer(&AnnotationClass, " authored");
CopyStringToBuffer(&Text,
"<span class=\"author\" style=\"color: #%X;\">%s</span> ",
StringToColourHash(HMML.annotations[AnnotationIndex].author),
HMML.annotations[AnnotationIndex].author);
StringToColourHash(Anno->author),
Anno->author);
}
InPtr = HMML.annotations[AnnotationIndex].text;
InPtr = Anno->text;
int MarkerIndex = 0, RefIndex = 0;
while(*InPtr)
while(*InPtr || RefIndex < Anno->reference_count)
{
if(MarkerIndex < HMML.annotations[AnnotationIndex].marker_count &&
InPtr - HMML.annotations[AnnotationIndex].text == HMML.annotations[AnnotationIndex].markers[MarkerIndex].offset)
if(MarkerIndex < Anno->marker_count &&
InPtr - Anno->text == Anno->markers[MarkerIndex].offset)
{
char *Readable = HMML.annotations[AnnotationIndex].markers[MarkerIndex].parameter
? HMML.annotations[AnnotationIndex].markers[MarkerIndex].parameter
: HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker;
if(HMML.annotations[AnnotationIndex].markers[MarkerIndex].type == HMML_MEMBER)
char *Readable = Anno->markers[MarkerIndex].parameter
? Anno->markers[MarkerIndex].parameter
: Anno->markers[MarkerIndex].marker;
if(Anno->markers[MarkerIndex].type == HMML_MEMBER)
{
CopyStringToBuffer(&Text,
"<a href=\"https://handmade.network/m/%s\" target=\"blank\" style=\"color: #%X; text-decoration: none\">%.*s</a>",
HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker,
StringToColourHash(HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker),
Anno->markers[MarkerIndex].marker,
StringToColourHash(Anno->markers[MarkerIndex].marker),
StringLength(Readable), InPtr);
InPtr += StringLength(Readable);
++MarkerIndex;
}
else if(HMML.annotations[AnnotationIndex].markers[MarkerIndex].type == HMML_PROJECT)
else if(Anno->markers[MarkerIndex].type == HMML_PROJECT)
{
CopyStringToBuffer(&Text,
"<a href=\"https://%s.handmade.network/\" target=\"blank\" style=\"color: #%X; text-decoration: none\">%s</a>",
HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker,
StringToColourHash(HMML.annotations[AnnotationIndex].markers[MarkerIndex].marker),
Anno->markers[MarkerIndex].marker,
StringToColourHash(Anno->markers[MarkerIndex].marker),
Readable);
InPtr += StringLength(Readable);
++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 &&
InPtr - HMML.annotations[AnnotationIndex].text == HMML.annotations[AnnotationIndex].references[RefIndex].offset)
if(RefIndex < Anno->reference_count &&
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;
++RefIdentifier;
}
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, "\"");
CopyBuffer(&AnnotationClass, &AnnotationHeader);
if(HasQuote || HasReference)
{
CopyStringToBuffer(&AnnotationData, "\"");
CopyBuffer(&AnnotationData, &AnnotationHeader);
}
CopyStringToBuffer(&AnnotationHeader, ">\n");
ClaimBuffer(MemoryArena, &ClaimedMemory, &Annotation, 1024 * 4);
@ -380,7 +496,7 @@ Readable);
CopyBuffer(&AnnotationHeader, &Annotation);
CopyStringToBuffer(&Annotation,
" <div class=\"content\"><span class=\"timecode\">%s</span>",
HMML.annotations[AnnotationIndex].time);
Anno->time);
if(HasCategory)
{
@ -395,7 +511,7 @@ HMML.annotations[AnnotationIndex].time);
CopyStringToBuffer(&Annotation, "</div>\n"
" <div class=\"progress faded\">\n"
" <div class=\"content\"><span class=\"timecode\">%s</span>",
HMML.annotations[AnnotationIndex].time);
Anno->time);
CopyBuffer(&Text, &Annotation);
@ -403,7 +519,7 @@ HMML.annotations[AnnotationIndex].time);
" </div>\n"
" <div class=\"progress main\">\n"
" <div class=\"content\"><span class=\"timecode\">%s</span>",
HMML.annotations[AnnotationIndex].time);
Anno->time);
CopyBuffer(&Text, &Annotation);
@ -420,6 +536,22 @@ HMML.annotations[AnnotationIndex].time);
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,
" <span class=\"annotator_container\">Annotator: <span class=\"annotator\">%s</span></span>\n"
" </div>\n", HMML.metadata.annotator);
@ -535,6 +667,9 @@ HMML.annotations[AnnotationIndex].time);
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;
}