hmml_to_html.c: CSV "-escaping [#20] and EDITION

EDITION gives us a way to conditionally handle and warn about features
that depend on network infrastructure, notably member / project info
This commit is contained in:
Matt Mascarenhas 2017-06-10 17:47:47 +01:00
parent 2f5057f36b
commit 95d0f63da0
1 changed files with 101 additions and 15 deletions

View File

@ -21,6 +21,13 @@ typedef unsigned int bool;
#define Kilobytes(Bytes) Bytes << 10
#define Megabytes(Bytes) Bytes << 20
enum
{
EDITION_SINGLE = 0,
EDITION_PROJECT = 1,
EDITION_NETWORK = 2
} EDITION;
typedef struct
{
char *Location;
@ -72,6 +79,8 @@ char *Credentials[ ][5] =
{ "abnercoimbre", "Abner Coimbre", "https://handmade.network/m/abnercoimbre", "patreon_logo.png", "https://patreon.com/handmade_dev"},
};
#define EDITION EDITION_SINGLE
#define ArrayCount(A) sizeof(A)/sizeof(*(A))
void
@ -239,6 +248,45 @@ CopyStringToBufferHTMLSafe(buffer *Dest, char *String)
}
}
void
CopyStringToBufferCSVSafe(buffer *Dest, char *String)
{
while(*String)
{
if(Dest->Ptr - Dest->Location >= Dest->Size)
{
fprintf(stderr, "CopyStringToBufferHTMLSafe: %s cannot accommodate %d-character string\n", Dest->ID, StringLength(String));
__asm__("int3");
}
switch(*String)
{
case '<':
CopyStringToBuffer(Dest, "&lt;");
String++;
break;
case '>':
CopyStringToBuffer(Dest, "&gt;");
String++;
break;
case '&':
CopyStringToBuffer(Dest, "&amp;");
String++;
break;
case '\"':
CopyStringToBuffer(Dest, "&quot;");
String += 2;
break;
case '\'':
CopyStringToBuffer(Dest, "&#39;");
String++;
break;
default:
*Dest->Ptr++ = *String++;
break;
}
}
}
int
StringsDiffer(char *A, char *B)
{
@ -257,7 +305,7 @@ StringsDifferL(char *A, char *B, int LengthofA)
{
++i;
}
if(!A[i] && LengthofA == i)
if(!A[i] && LengthofA == i && B[i] == ' ')
{
return FALSE;
}
@ -674,8 +722,6 @@ BuildQuote(quote_info *Info, char *Speaker, int ID)
{
// TODO(matt): Pull these paths from the config
// Also notable that there are different paths for different projects
//
// TODO(matt): Handle csv's double quote escaping stuff
char *QuoteDir = "/home/matt/git/GitHub/insofaras/25fc16d58a297a486334";
if(!StringsDiffer(Speaker, "handmade_hero"))
@ -708,7 +754,6 @@ BuildQuote(quote_info *Info, char *Speaker, int ID)
while(InPtr - Buffer < Length)
{
char InID[4] = { 0 };
char *OutPtr = InID;
while(*InPtr != ',')
@ -1282,11 +1327,26 @@ TimecodeToSeconds(Anno->time));
CopyStringToBuffer(&AnnotationClass, " authored");
hsl_colour AuthorColour;
StringToColourHash(&AuthorColour, Anno->author);
CopyStringToBuffer(&Text,
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,
"<a class=\"author\" href=\"https://handmade.network/m/%s\" target=\"blank\" style=\"color: hsl(%d, %d%%, %d%%); text-decoration: none\" data-hue=\"%d\" data-saturation=\"%d%%\">%s</a> ",
Anno->author,
AuthorColour.Hue, AuthorColour.Saturation, AuthorColour.Lightness,
AuthorColour.Hue, AuthorColour.Saturation,
Anno->author);
}
else
{
CopyStringToBuffer(&Text,
"<span class=\"author\" style=\"color: hsl(%d, %d%%, %d%%);\" data-hue=\"%d\" data-saturation=\"%d%%\">%s</span> ",
AuthorColour.Hue, AuthorColour.Saturation, AuthorColour.Lightness,
AuthorColour.Hue, AuthorColour.Saturation,
Anno->author);
}
if(!HasMedium)
{
HasMedium = TRUE;
@ -1308,14 +1368,26 @@ Anno->author);
{
hsl_colour MemberColour;
StringToColourHash(&MemberColour, Anno->markers[MarkerIndex].marker);
CopyStringToBuffer(&Text,
// TODO(matt): Hoverbox
// We should get instructions on how to get this info in the config
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,
"<a class=\"member\" href=\"https://handmade.network/m/%s\" target=\"blank\" style=\"color: hsl(%d, %d%%, %d%%); text-decoration: none\" data-hue=\"%d\" data-saturation=\"%d%%\">%.*s</a>",
Anno->markers[MarkerIndex].marker,
MemberColour.Hue, MemberColour.Saturation, MemberColour.Lightness,
MemberColour.Hue, MemberColour.Saturation,
StringLength(Readable), InPtr);
}
else
{
CopyStringToBuffer(&Text,
"<span class=\"member\" style=\"color: hsl(%d, %d%%, %d%%);\" data-hue=\"%d\" data-saturation=\"%d%%\">%.*s</span>",
MemberColour.Hue, MemberColour.Saturation, MemberColour.Lightness,
MemberColour.Hue, MemberColour.Saturation,
StringLength(Readable), InPtr);
}
InPtr += StringLength(Readable);
++MarkerIndex;
}
@ -1323,14 +1395,25 @@ StringLength(Readable), InPtr);
{
hsl_colour ProjectColour;
StringToColourHash(&ProjectColour, Anno->markers[MarkerIndex].marker);
CopyStringToBuffer(&Text,
// TODO(matt): Hoverbox
// We should get instructions on how to get this info in the config
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,
"<a class=\"project\" href=\"https://%s.handmade.network/\" target=\"blank\" style=\"color: hsl(%d, %d%%, %d%%); text-decoration: none\" data-hue=\"%d\" data-saturation=\"%d%%\">%s</a>",
Anno->markers[MarkerIndex].marker,
ProjectColour.Hue, ProjectColour.Saturation, ProjectColour.Lightness,
ProjectColour.Hue, ProjectColour.Saturation,
Readable);
}
else
{
CopyStringToBuffer(&Text,
"<span class=\"project\" style=\"color: hsl(%d, %d%%, %d%%);\" data-hue=\"%d\" data-saturation=\"%d%%\">%s</span>",
ProjectColour.Hue, ProjectColour.Saturation, ProjectColour.Lightness,
ProjectColour.Hue, ProjectColour.Saturation,
Readable);
}
InPtr += StringLength(Readable);
++MarkerIndex;
}
@ -1539,16 +1622,19 @@ AppendedIdentifier:
" <span data-id=\"&#%d;\" class=\"ref\">\n"
" <span class=\"ref_content\">\n"
" <div class=\"source\">Quote %d</div>\n"
" <div class=\"ref_title\">%s</div>\n"
" <div class=\"ref_title\">",
QuoteIdentifier,
Anno->quote.id);
CopyStringToBufferCSVSafe(&QuoteMenu, QuoteInfo.Text);
CopyStringToBuffer(&QuoteMenu, "</div>\n"
" <div class=\"quote_byline\">&mdash;%s, %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,
QuoteInfo.Text,
HMML.metadata.twitch ? HMML.metadata.twitch : HMML.metadata.member,
QuoteInfo.Date,
TimecodeToSeconds(Anno->time),