hmml_to_html.c: Fix reference bugs

* Comma separation of > 2 ref identifiers at the same offset
* Fix multiple refs all at the same (possibly not -1) offset
* Reference combinations, use flags to ensure we are using a valid
  combination

We also tried to handle quote speakers other than the host, but appeared
to hit a bug in hmmlib.h in which the quote.author got set to "quote"
for the second (and subsequent) quote node in a set of annotations
This commit is contained in:
Matt Mascarenhas 2017-07-30 00:01:39 +01:00
parent b3d1399237
commit c59a4fcc5a
1 changed files with 70 additions and 18 deletions

View File

@ -51,7 +51,7 @@ typedef struct
int Identifier; int Identifier;
} identifier; } identifier;
#define REF_MAX_IDENTIFIER 55 #define REF_MAX_IDENTIFIER 64
typedef struct typedef struct
{ {
@ -538,35 +538,74 @@ BuildCredits(buffer *CreditsMenu, buffer *HostInfo, buffer *AnnotatorInfo, bool
int 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.url && Ref.title && Ref.author && Ref.publisher && Ref.isbn)
#define REF_SITE (1 << 0)
#define REF_PAGE (1 << 1)
#define REF_URL (1 << 2)
#define REF_TITLE (1 << 3)
#define REF_ARTICLE (1 << 4)
#define REF_AUTHOR (1 << 5)
#define REF_EDITOR (1 << 6)
#define REF_PUBLISHER (1 << 7)
#define REF_ISBN (1 << 8)
int Mask = 0;
if(Ref.site) { Mask |= REF_SITE; }
if(Ref.page) { Mask |= REF_PAGE; }
if(Ref.url) { Mask |= REF_URL; }
if(Ref.title) { Mask |= REF_TITLE; }
if(Ref.article) { Mask |= REF_ARTICLE; }
if(Ref.author) { Mask |= REF_AUTHOR; }
if(Ref.editor) { Mask |= REF_EDITOR; }
if(Ref.publisher) { Mask |= REF_PUBLISHER; }
if(Ref.isbn) { Mask |= REF_ISBN; }
/*
* NOTE(matt)
*
* Mask
* Loop over the reference attributes, adding them to a mask if they are set
* Then my cases will just be that mask tested against the attributes OR'd with each other
*
*/
if((REF_URL | REF_TITLE | REF_AUTHOR | REF_PUBLISHER | REF_ISBN) == Mask)
{ {
CopyString(ReferencesArray[UniqueRefs].ID, Ref.isbn); CopyString(ReferencesArray[UniqueRefs].ID, Ref.isbn);
CopyString(ReferencesArray[UniqueRefs].Source, "%s (%s)", Ref.author, Ref.publisher); CopyString(ReferencesArray[UniqueRefs].Source, "%s (%s)", Ref.author, Ref.publisher);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url);
} }
else if(Ref.page && Ref.url && Ref.title) else if((REF_AUTHOR | REF_SITE | REF_PAGE | REF_URL) == Mask)
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref.site);
CopyString(ReferencesArray[UniqueRefs].RefTitle, "%s: \"%s\"", Ref.author, Ref.page);
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url);
}
else if((REF_PAGE | REF_URL | REF_TITLE) == Mask)
{ {
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref.title); CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref.title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.page); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.page);
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url);
} }
else if(Ref.site && Ref.page && Ref.url) else if((REF_SITE | REF_PAGE | REF_URL) == Mask)
{ {
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref.site); CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref.site);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.page); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.page);
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url);
} }
else if(Ref.site && Ref.url && Ref.title) else if((REF_SITE | REF_URL | REF_TITLE) == Mask)
{ {
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref.site); CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref.site);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url);
} }
else if(Ref.title && Ref.author && Ref.isbn) else if((REF_TITLE | REF_AUTHOR | REF_ISBN) == Mask)
{ {
CopyString(ReferencesArray[UniqueRefs].ID, Ref.isbn); CopyString(ReferencesArray[UniqueRefs].ID, Ref.isbn);
CopyString(ReferencesArray[UniqueRefs].Source, Ref.author); CopyString(ReferencesArray[UniqueRefs].Source, Ref.author);
@ -574,27 +613,27 @@ BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMM
//TODO(matt): Look into finding the best ISBN searcher the web has to offer //TODO(matt): Look into finding the best ISBN searcher the web has to offer
CopyString(ReferencesArray[UniqueRefs].URL, "http://www.openisbn.com/isbn/%s", Ref.isbn); CopyString(ReferencesArray[UniqueRefs].URL, "http://www.openisbn.com/isbn/%s", Ref.isbn);
} }
else if(Ref.url && Ref.article && Ref.author) else if((REF_URL | REF_ARTICLE | REF_AUTHOR) == Mask)
{ {
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyString(ReferencesArray[UniqueRefs].Source, Ref.author); CopyString(ReferencesArray[UniqueRefs].Source, Ref.author);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.article); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.article);
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url);
} }
else if(Ref.url && Ref.title && Ref.author) else if((REF_URL | REF_TITLE | REF_AUTHOR) == Mask)
{ {
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyString(ReferencesArray[UniqueRefs].Source, Ref.author); CopyString(ReferencesArray[UniqueRefs].Source, Ref.author);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url);
} }
else if(Ref.url && Ref.title) else if((REF_URL | REF_TITLE) == Mask)
{ {
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref.url);
} }
else if(Ref.site && Ref.url) else if((REF_SITE | REF_URL) == Mask)
{ {
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url); CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref.url);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.site); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.site);
@ -1495,7 +1534,7 @@ main(int ArgC, char **Args)
ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationHeader, "AnnotationHeader", 512); ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationHeader, "AnnotationHeader", 512);
ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationClass, "AnnotationClass", 256); ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationClass, "AnnotationClass", 256);
ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationData, "AnnotationData", 256); ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationData, "AnnotationData", 512);
ClaimBuffer(&MemoryArena, &ClaimedMemory, &Text, "Text", Kilobytes(4)); ClaimBuffer(&MemoryArena, &ClaimedMemory, &Text, "Text", Kilobytes(4));
ClaimBuffer(&MemoryArena, &ClaimedMemory, &Category, "Category", 512); ClaimBuffer(&MemoryArena, &ClaimedMemory, &Category, "Category", 512);
@ -1619,7 +1658,7 @@ main(int ArgC, char **Args)
} }
} }
if(RefIndex < Anno->reference_count && while(RefIndex < Anno->reference_count &&
InPtr - Anno->text == Anno->references[RefIndex].offset) InPtr - Anno->text == Anno->references[RefIndex].offset)
{ {
HMML_Reference *CurrentRef = Anno->references + RefIndex; HMML_Reference *CurrentRef = Anno->references + RefIndex;
@ -1633,7 +1672,11 @@ main(int ArgC, char **Args)
if(BuildReference(ReferencesArray, RefIdentifier, UniqueRefs, *CurrentRef, *Anno) == 1) if(BuildReference(ReferencesArray, RefIdentifier, UniqueRefs, *CurrentRef, *Anno) == 1)
{ {
fprintf(stderr, "%s:%d: Cannot process new combination of reference info\n", Args[FileIndex], Anno->line); fprintf(stderr, "%s:%d: Cannot process new combination of reference info\n"
"\n"
"Either tweak your annotation, or contact matt@handmadedev.org\n"
"mentioning the ref node you want to write and how you want it to\n"
"appear in the references menu\n", Args[FileIndex], Anno->line);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
return 1; return 1;
@ -1685,7 +1728,11 @@ main(int ArgC, char **Args)
if(BuildReference(ReferencesArray, RefIdentifier, UniqueRefs, *CurrentRef, *Anno) == 1) if(BuildReference(ReferencesArray, RefIdentifier, UniqueRefs, *CurrentRef, *Anno) == 1)
{ {
fprintf(stderr, "%s:%d: Cannot process new combination of reference info\n", Args[FileIndex], Anno->line); fprintf(stderr, "%s:%d: Cannot process new combination of reference info\n"
"\n"
"Either tweak your annotation, or contact matt@handmadedev.org\n"
"mentioning the ref node you want to write and how you want it to\n"
"appear in the references menu\n", Args[FileIndex], Anno->line);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
return 1; return 1;
@ -1733,7 +1780,7 @@ main(int ArgC, char **Args)
} }
} }
if(RefIndex > 1 && Anno->references[RefIndex].offset == Anno->references[RefIndex-1].offset) if(Anno->references[RefIndex].offset == Anno->references[RefIndex-1].offset)
{ {
CopyStringToBuffer(&Text, "<sup>,%d</sup>", RefIdentifier); CopyStringToBuffer(&Text, "<sup>,%d</sup>", RefIdentifier);
} }
@ -1802,12 +1849,17 @@ main(int ArgC, char **Args)
HasQuote = TRUE; HasQuote = TRUE;
if(BuildQuote(&QuoteInfo, HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, Anno->quote.id, QuoteDir) == 1) // TODO(matt): QUOTE
if(Anno->quote.author)
{
printf("%s\n", Anno->quote.author);
}
if(BuildQuote(&QuoteInfo, Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, Anno->quote.id, QuoteDir) == 1)
{ {
fprintf(stderr, "%s:%d: Quote #%s %d not found! Consider pulling the latest quotes\n", fprintf(stderr, "%s:%d: Quote #%s %d not found! Consider pulling the latest quotes\n",
Args[FileIndex], Args[FileIndex],
Anno->line, Anno->line,
HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member,
Anno->quote.id); Anno->quote.id);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
@ -1831,7 +1883,7 @@ main(int ArgC, char **Args)
" <span data-timestamp=\"%d\" class=\"timecode\"><span class=\"ref_index\">[&#%d;]</span><span class=\"time\">%s</span></span>\n" " <span data-timestamp=\"%d\" class=\"timecode\"><span class=\"ref_index\">[&#%d;]</span><span class=\"time\">%s</span></span>\n"
" </div>\n" " </div>\n"
" </span>\n", " </span>\n",
HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member,
QuoteInfo.Date, QuoteInfo.Date,
TimecodeToSeconds(Anno->time), TimecodeToSeconds(Anno->time),
QuoteIdentifier, QuoteIdentifier,