From 8dffa513cc1c4678c99b72c64fd3bb8865ef193c Mon Sep 17 00:00:00 2001 From: Matt Mascarenhas Date: Sun, 21 Aug 2022 19:15:10 +0100 Subject: [PATCH] cinera: Add tag __CINERA_PROJECT_LINEAGE _ --- cinera/cinera.c | 6 +++++- cinera/cinera_config.c | 41 ++++++++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/cinera/cinera.c b/cinera/cinera.c index 0fe55dc..a617c3b 100644 --- a/cinera/cinera.c +++ b/cinera/cinera.c @@ -23,7 +23,7 @@ typedef struct version CINERA_APP_VERSION = { .Major = 0, .Minor = 10, - .Patch = 9 + .Patch = 10 }; #include // NOTE(matt): varargs @@ -2845,6 +2845,7 @@ typedef enum // TAG_PATHED_NAV, TAG_PROJECT, TAG_PROJECT_ID, + TAG_PROJECT_LINEAGE, TAG_PROJECT_PLAIN, TAG_SEARCH_URL, TAG_THEME, @@ -2890,6 +2891,7 @@ char *TemplateTags[] = { //"__CINERA_PATHED_NAV__", "__CINERA_PROJECT__", "__CINERA_PROJECT_ID__", + "__CINERA_PROJECT_LINEAGE__", "__CINERA_PROJECT_PLAIN__", "__CINERA_SEARCH_URL__", "__CINERA_THEME__", @@ -8424,6 +8426,7 @@ NextTagSearch: } goto RecordTag; case TAG_PROJECT: case TAG_PROJECT_ID: + case TAG_PROJECT_LINEAGE: case TAG_PROJECT_PLAIN: { if(Type == TEMPLATE_GLOBAL_SEARCH) @@ -11470,6 +11473,7 @@ BuffersToHTML(config *C, project *Project, buffers *CollationBuffers, template * else { CopyStringToBufferHTMLSafe(&Master, Project->Title); } } break; case TAG_PROJECT_ID: CopyStringToBufferNoFormat(&Master, Project->ID); break; // NOTE(matt): Not HTML-safe + case TAG_PROJECT_LINEAGE: CopyStringToBufferHTMLSafe(&Master, Project->WrittenLineage); break; case TAG_PROJECT_PLAIN: CopyStringToBufferHTMLSafe(&Master, Project->Title); break; case TAG_SEARCH_URL: CopyStringToBufferNoFormat(&Master, Wrap0i(CollationBuffers->URLSearch, sizeof(CollationBuffers->URLSearch))); break; // NOTE(matt): Not HTML-safe case TAG_THEME: CopyStringToBufferNoFormat(&Master, Project->Theme); break; // NOTE(matt): Not HTML-safe diff --git a/cinera/cinera_config.c b/cinera/cinera_config.c index e3f37bb..98064f2 100644 --- a/cinera/cinera_config.c +++ b/cinera/cinera_config.c @@ -504,6 +504,7 @@ typedef struct project { string ID; string Lineage; + string WrittenLineage; string Title; string HTMLTitle; @@ -2650,26 +2651,49 @@ GetPerson(config *C, resolution_errors *E, config_pair *PersonID) return Result; } +typedef enum +{ + LT_INTERNAL_ID, // e.g. hms/2019/devon + LT_EXTERNAL_FULL, // e.g. Handmade Seattle / 2019 / Devon's Journey +} lineage_type; + string -DeriveLineageOfProject(config *C, scope_tree *Project) +DeriveLineageOfProject(config *C, scope_tree *Project, lineage_type Type) { string Result = {}; + string NullTitle = Wrap0("(null)"); memory_book StringList = InitBookOfPointers(4); if(Project) { string **Writer = MakeSpaceInBook(&StringList); - *Writer = &Project->ID.String; + switch(Type) + { + case LT_INTERNAL_ID: { *Writer = &Project->ID.String; } break; + case LT_EXTERNAL_FULL: { + config_pair *Title = GetPair(Project, IDENT_TITLE); + if(Title) { *Writer = &Title->String; } + else { *Writer = &NullTitle; } + } break; + } Project = Project->Parent; } - string Slash = Wrap0("/"); + string Divider = Wrap0(Type == LT_INTERNAL_ID ? "/" : " / "); while(Project && Project->ID.Key == IDENT_PROJECT) { string **Writer = MakeSpaceInBook(&StringList); - *Writer = &Slash; + *Writer = &Divider; Writer = MakeSpaceInBook(&StringList); - *Writer = &Project->ID.String; + switch(Type) + { + case LT_INTERNAL_ID: { *Writer = &Project->ID.String; } break; + case LT_EXTERNAL_FULL: { + config_pair *Title = GetPair(Project, IDENT_TITLE); + if(Title) { *Writer = &Title->String; } + else { *Writer = &NullTitle; } + } break; + } Project = Project->Parent; } @@ -2740,7 +2764,7 @@ ResolveLocalVariable(config *C, resolution_errors *E, scope_tree *Scope, config_ { if(Scope->ID.Key == IDENT_PROJECT) { - Result = DeriveLineageOfProject(C, Scope); + Result = DeriveLineageOfProject(C, Scope, LT_INTERNAL_ID); } else { @@ -3378,7 +3402,7 @@ PushProject(config *C, resolution_errors *E, config_verifiers *V, project *P, sc } ResetPen(&C->ResolvedVariables); - P->Lineage = DeriveLineageOfProject(C, ProjectTree); + P->Lineage = DeriveLineageOfProject(C, ProjectTree, LT_INTERNAL_ID); // NOTE(matt): Initial pass over as-yet unresolvable local variable(s) // @@ -3525,6 +3549,9 @@ PushProject(config *C, resolution_errors *E, config_verifiers *V, project *P, sc } } + ResetPen(&C->ResolvedVariables); + P->WrittenLineage = DeriveLineageOfProject(C, ProjectTree, LT_EXTERNAL_FULL); + for(int i = 0; i < ProjectTree->Trees.ItemCount; ++i) { scope_tree *This = GetPlaceInBook(&ProjectTree->Trees, i);