From c59a4fcc5a964c6ac12f14581242802489d7a8e8 Mon Sep 17 00:00:00 2001 From: Matt Mascarenhas Date: Sun, 30 Jul 2017 00:01:39 +0100 Subject: [PATCH] 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 --- hmml_to_html/hmml_to_html.c | 88 +++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 18 deletions(-) diff --git a/hmml_to_html/hmml_to_html.c b/hmml_to_html/hmml_to_html.c index 524f4f5..2ee634b 100644 --- a/hmml_to_html/hmml_to_html.c +++ b/hmml_to_html/hmml_to_html.c @@ -51,7 +51,7 @@ typedef struct int Identifier; } identifier; -#define REF_MAX_IDENTIFIER 55 +#define REF_MAX_IDENTIFIER 64 typedef struct { @@ -538,35 +538,74 @@ BuildCredits(buffer *CreditsMenu, buffer *HostInfo, buffer *AnnotatorInfo, bool int 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].Source, "%s (%s)", Ref.author, Ref.publisher); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title); 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].Source, Ref.title); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.page); 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].Source, Ref.site); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.page); 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].Source, Ref.site); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title); 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].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 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); CopyString(ReferencesArray[UniqueRefs].Source, Ref.author); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.article); 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); CopyString(ReferencesArray[UniqueRefs].Source, Ref.author); CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref.title); 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].RefTitle, Ref.title); 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].RefTitle, Ref.site); @@ -1495,7 +1534,7 @@ main(int ArgC, char **Args) ClaimBuffer(&MemoryArena, &ClaimedMemory, &AnnotationHeader, "AnnotationHeader", 512); 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, &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) { HMML_Reference *CurrentRef = Anno->references + RefIndex; @@ -1633,7 +1672,11 @@ main(int ArgC, char **Args) 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); free(MemoryArena.Location); return 1; @@ -1685,7 +1728,11 @@ main(int ArgC, char **Args) 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); free(MemoryArena.Location); 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, ",%d", RefIdentifier); } @@ -1802,12 +1849,17 @@ main(int ArgC, char **Args) 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", Args[FileIndex], 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); hmml_free(&HMML); free(MemoryArena.Location); @@ -1831,7 +1883,7 @@ main(int ArgC, char **Args) " [&#%d;]%s\n" " \n" " \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, TimecodeToSeconds(Anno->time), QuoteIdentifier,