diff --git a/cinera/cinera.c b/cinera/cinera.c
index 412ff93..c833edd 100644
--- a/cinera/cinera.c
+++ b/cinera/cinera.c
@@ -23,7 +23,7 @@ typedef struct
version CINERA_APP_VERSION = {
.Major = 0,
.Minor = 10,
- .Patch = 15
+ .Patch = 16
};
#define __USE_XOPEN2K8 // NOTE(matt): O_NOFOLLOW
@@ -971,6 +971,17 @@ StringContains(string S, string Substring)
return Result;
}
+int
+StringContainsXOfChar(string S, char C)
+{
+ int Result = 0;
+ for(int i = 0; i < S.Length; ++i)
+ {
+ Result += S.Base[i] == C;
+ }
+ return Result;
+}
+
bool
StringsMatchCaseInsensitive(string A, string B)
{
@@ -1413,6 +1424,9 @@ typedef struct
config_identifier ConfigIdentifiers[] =
{
{ "" },
+ { "abbrev_dotted_initial_and_surname", "The dotted-initial(s) and surname of a person's name, used to override the auto-derived one, e.g. J. R. R. Tolkien (from John Ronald Reuel Tolkien) or J. du Pré (from Jacqueline du Pré)" },
+ { "abbrev_given_or_nickname", "The given or quoted nickname of a person's name, used to override the auto-derived one, e.g. Charlotte (from Charlotte Brontë) or Ry (from Ryland Peter \"Ry\" Cooder)" },
+ { "abbrev_initial", "The initials of a person's name, used to override the auto-derived ones, e.g. KB (from Kate Bush)" },
{ "allow",
"An include-rule string of the forms: \"identifier\", \"type.member\" or \"type.member.member\", etc. For example:\n\nallow = \"project.default_medium\";\n\nAdding an \"allow\" / \"deny\" rule makes the inclusion prohibitive or permissive, respectively, \
and they cannot be mixed (i.e. only \"allow\" rules, or only \"deny\" rules)."
@@ -1557,6 +1571,9 @@ fill the slots left vacant by positioned roles in the order in which they are co
typedef enum
{
IDENT_NULL,
+ IDENT_ABBREV_DOTTED_INITIAL_AND_SURNAME,
+ IDENT_ABBREV_GIVEN_OR_NICKNAME,
+ IDENT_ABBREV_INITIAL,
IDENT_ALLOW,
IDENT_ART,
IDENT_ART_VARIANTS,
@@ -1944,6 +1961,22 @@ ConfigError(string *Filename, uint64_t LineNumber, severity Severity, char *Mess
fprintf(stderr, "\n");
}
+void
+ConfigErrorField(string *Filename, uint64_t LineNumber, severity Severity, config_identifier_id FieldID,
+ char *Message, string *Received)
+{
+ ErrorFilenameAndLineNumber(Filename, LineNumber, Severity, ED_CONFIG);
+ fprintf(stderr,
+ "Faulty %s%s%s %s",
+ ColourStrings[CS_YELLOW_BOLD], ConfigIdentifiers[FieldID].String, ColourStrings[CS_END],
+ Message);
+ if(Received)
+ {
+ PrintStringC(CS_MAGENTA_BOLD, *Received);
+ }
+ fprintf(stderr, "\n");
+}
+
void
ConfigErrorUnset(config_identifier_id FieldID)
{
@@ -1952,6 +1985,19 @@ ConfigErrorUnset(config_identifier_id FieldID)
"Unset %s\n", ConfigIdentifiers[FieldID].String);
}
+void
+ConfigErrorUnsetFieldOf(string *Filename, uint64_t LineNumber,
+ config_identifier_id UnsetFieldID,
+ config_identifier_id ScopeKey, string ScopeID)
+{
+ ErrorFilenameAndLineNumber(Filename, LineNumber, S_ERROR, ED_CONFIG);
+ fprintf(stderr,
+ "Unset %s%s%s of %s%s%s: %s%.*s%s\n",
+ ColourStrings[CS_YELLOW_BOLD], ConfigIdentifiers[UnsetFieldID].String, ColourStrings[CS_END],
+ ColourStrings[CS_YELLOW_BOLD], ConfigIdentifiers[ScopeKey].String, ColourStrings[CS_END],
+ ColourStrings[CS_GREEN_BOLD], (int)ScopeID.Length, ScopeID.Base, ColourStrings[CS_END]);
+}
+
void
ConfigErrorSizing(string *Filename, uint64_t LineNumber, config_identifier_id FieldID, string *Received, uint64_t MaxSize)
{
@@ -5091,14 +5137,13 @@ typedef struct
{
hsl_colour Colour;
person *Person;
- string Abbreviation;
bool Seen;
} speaker;
typedef struct
{
_memory_book(speaker) Speakers;
- memory_book Abbreviations;
+ abbreviation_scheme AbbrevScheme;
} speakers;
enum
@@ -6837,94 +6882,38 @@ ConstructResolvedAssetURL(buffer *Buffer, asset *Asset, page_type PageType)
Free(ResolvablePath);
}
-string
-InitialString(memory_book *Abbreviations, string Src)
+void
+PickAbbreviationScheme(speakers *Speakers)
{
- ResetPen(Abbreviations);
- string Result = {};
- string Char = Wrap0i_(Src.Base, 1);
-
- Result = ExtendStringInBook(Abbreviations, Char);
- for(int i = 1; i < Src.Length; ++i)
+ Speakers->AbbrevScheme = AS_NONE;
+ int SchemeCount = 3;
+ for(int SchemeIndex = 0; SchemeIndex < SchemeCount; ++SchemeIndex)
{
- if(Src.Base[i] == ' ' && i < Src.Length)
+ bool Clash = FALSE;
+ for(int i = 0; i < Speakers->Speakers.ItemCount; ++i)
{
- ++i;
- Char = Wrap0i_(Src.Base + i, 1);
- Result = ExtendStringInBook(Abbreviations, Char);
- }
- }
- return Result;
-}
-
-string
-GetFirstSubstring(string Src)
-{
- string Result = Src;
- for(Result.Length = 0; Result.Length < Src.Length && Result.Base[Result.Length] != ' '; ++Result.Length) { }
- return Result;
-}
-
-string
-InitialAndGetFinalString(memory_book *Abbreviations, string Src)
-{
- ResetPen(Abbreviations);
- string Result = {};
- int FinalStringBase;
- for(FinalStringBase = Src.Length; FinalStringBase > 0; --FinalStringBase)
- {
- if(Src.Base[FinalStringBase - 1] == ' ') { break; }
- }
-
- if(FinalStringBase > 0 && Src.Base[FinalStringBase] == ' ' && FinalStringBase < Src.Length)
- {
- ++FinalStringBase;
- }
-
- string FinalString = Wrap0i_(Src.Base + FinalStringBase, Src.Length - FinalStringBase);
-
- if(FinalStringBase > 0)
- {
- string Initial = Wrap0i_(Src.Base, 1);
- Result = ExtendStringInBook(Abbreviations, Initial);
- Result = ExtendStringInBook(Abbreviations, Wrap0(". "));
-
- for(int i = 0; i < FinalStringBase; ++i)
- {
- if(Src.Base[i] == ' ' && i + 1 < FinalStringBase)
+ speaker *A = GetPlaceInBook(&Speakers->Speakers, i);
+ for(int j = i + 1; j < Speakers->Speakers.ItemCount; ++j)
{
- ++i;
- string Initial = Wrap0i_(Src.Base + i, 1);
- Result = ExtendStringInBook(Abbreviations, Initial);
- Result = ExtendStringInBook(Abbreviations, Wrap0(". "));
+ speaker *B = GetPlaceInBook(&Speakers->Speakers, j);
+ if(StringsMatch(A->Person->Abbreviations[SchemeIndex], B->Person->Abbreviations[SchemeIndex]))
+ {
+ Clash = TRUE;
+ break;
+ }
}
+ if(Clash) { break; }
}
- }
-
- Result = ExtendStringInBook(Abbreviations, FinalString);
- return Result;
-}
-
-bool
-AbbreviationsClash(memory_book *Speakers)
-{
- for(int i = 0; i < Speakers->ItemCount; ++i)
- {
- speaker *A = GetPlaceInBook(Speakers, i);
- for(int j = i + 1; j < Speakers->ItemCount; ++j)
+ if(!Clash)
{
- speaker *B = GetPlaceInBook(Speakers, j);
- if(StringsMatch(A->Abbreviation, B->Abbreviation))
- {
- return TRUE;
- }
+ Speakers->AbbrevScheme = SchemeIndex;
+ break;
}
}
- return FALSE;
}
void
-SortAndAbbreviateSpeakers(speakers *Speakers)
+SortSpeakersAndPickAbbreviationScheme(speakers *Speakers)
{
for(int i = 0; i < Speakers->Speakers.ItemCount; ++i)
{
@@ -6945,26 +6934,10 @@ SortAndAbbreviateSpeakers(speakers *Speakers)
for(int i = 0; i < Speakers->Speakers.ItemCount; ++i)
{
speaker *This = GetPlaceInBook(&Speakers->Speakers, i);
- string Name = This->Person->Name.Length > 0 ? This->Person->Name : This->Person->ID;
StringToColourHash(&This->Colour, This->Person->ID);
- This->Abbreviation = InitialString(&Speakers->Abbreviations, Name);
}
- int MaxAttemptCount = 3;
- for(int Attempt = 0; Attempt < MaxAttemptCount && AbbreviationsClash(&Speakers->Speakers); ++Attempt)
- {
- for(int i = 0; i < Speakers->Speakers.ItemCount; ++i)
- {
- speaker *This = GetPlaceInBook(&Speakers->Speakers, i);
- string Name = This->Person->Name.Length > 0 ? This->Person->Name : This->Person->ID;
- switch(Attempt)
- {
- case 0: This->Abbreviation = GetFirstSubstring(Name); break;
- case 1: This->Abbreviation = InitialAndGetFinalString(&Speakers->Abbreviations, Name); break;
- case 2: This->Abbreviation = Name; break;
- }
- }
- }
+ PickAbbreviationScheme(Speakers);
}
person *
@@ -7359,7 +7332,6 @@ void
FreeSpeakers(speakers *Speakers)
{
FreeBook(&Speakers->Speakers);
- FreeBook(&Speakers->Abbreviations);
}
void
@@ -7644,11 +7616,11 @@ BuildCredits(string HMMLFilepath, buffer *CreditsMenu, HMML_VideoMetaData *Metad
}
FreeBook(&Credits);
- // NOTE(matt): As we only cite the speaker when there are a multiple of them, we only need to SortAndAbbreviateSpeakers()
- // in the same situation
+ // NOTE(matt): As we only cite the speaker when there are a multiple of them, we only
+ // need to SortSpeakersAndPickAbbreviationScheme() in the same situation
if(Speakers->Speakers.ItemCount > 1)
{
- SortAndAbbreviateSpeakers(Speakers);
+ SortSpeakersAndPickAbbreviationScheme(Speakers);
}
if(CreditsMenu->Ptr > CreditsMenu->Location)
@@ -10093,7 +10065,6 @@ InitSpeakers()
{
speakers Result = {};
Result.Speakers = InitBook(sizeof(speaker), 4);
- Result.Abbreviations = InitBookOfStrings(64);
return Result;
}
@@ -10385,14 +10356,22 @@ ProcessTimestamp(buffers *CollationBuffers, neighbourhood *N, string Filepath, m
// NOTE(matt): I reckon it's fair to only cite the speaker when there are a multiple of them
if(Speakers->Speakers.ItemCount > 1 && Speaker && !IsCategorisedAuthored(Timestamp))
{
- string DisplayName = !Speaker->Seen ? Speaker->Person->Name : Speaker->Abbreviation;
+ string DisplayName = !Speaker->Seen ? Speaker->Person->Name : Speaker->Person->Abbreviations[Speakers->AbbrevScheme];
CopyStringToBuffer(&IndexBuffers->Text,
- "%.*s: ",
+ "Colour.Hue,
- Speaker->Colour.Saturation,
+ Speaker->Colour.Saturation);
- (int)DisplayName.Length, DisplayName.Base);
+ if(Speaker->Seen)
+ {
+ CopyStringToBuffer(&IndexBuffers->Text, " title=\"");
+ CopyStringToBufferHTMLSafe(&IndexBuffers->Text, Speaker->Person->Name);
+ CopyStringToBuffer(&IndexBuffers->Text, "\"");
+ }
+
+ CopyStringToBuffer(&IndexBuffers->Text,
+ ">%.*s: ", (int)DisplayName.Length, DisplayName.Base);
Speaker->Seen = TRUE;
}
@@ -16084,7 +16063,6 @@ InsertProjectIntoDB(project_generations *G, db_block_projects **Block, db_header
uint64_t Byte = 0;
OpenFileForWriting(&DB.Metadata.File);
- WriteFromByteToPointer(&DB.Metadata.File, &Byte, *Block);
uint64_t PPos;
if(GotBlock)
@@ -17258,11 +17236,8 @@ MonitorFilesystem(neighbourhood *N, buffers *CollationBuffers, template *Bespoke
} break;
case WT_CONFIG:
{
- if(Config)
- {
- DiscardAllAndFreeConfig();
- PushWatchHandle(ConfigPath, EXT_NULL, WT_CONFIG, 0, 0);
- }
+ DiscardAllAndFreeConfig();
+ PushWatchHandle(ConfigPath, EXT_NULL, WT_CONFIG, 0, 0);
ParseAndEitherPrintConfigOrInitAll(ConfigPath, TokensList, N, CollationBuffers, BespokeTemplate);
} break;
@@ -17400,7 +17375,7 @@ main(int ArgC, char **Args)
if(ClaimBuffer(&CollationBuffers.IncludesPlayer, BID_COLLATION_BUFFERS_INCLUDES_PLAYER, Kilobytes(2)) == RC_ARENA_FULL) { Exit(); };
if(ClaimBuffer(&CollationBuffers.Player, BID_COLLATION_BUFFERS_PLAYER, Kilobytes(552)) == RC_ARENA_FULL) { Exit(); };
- if(ClaimBuffer(&CollationBuffers.IncludesSearch, BID_COLLATION_BUFFERS_INCLUDES_SEARCH, Kilobytes(2)) == RC_ARENA_FULL) { Exit(); };
+ if(ClaimBuffer(&CollationBuffers.IncludesSearch, BID_COLLATION_BUFFERS_INCLUDES_SEARCH, Kilobytes(4)) == RC_ARENA_FULL) { Exit(); };
if(ClaimBuffer(&CollationBuffers.SearchEntry, BID_COLLATION_BUFFERS_SEARCH_ENTRY, Kilobytes(32)) == RC_ARENA_FULL) { Exit(); };
CollationBuffers.Search.ID = BID_COLLATION_BUFFERS_SEARCH; // NOTE(matt): Allocated by SearchToBuffer()
diff --git a/cinera/cinera_config.c b/cinera/cinera_config.c
index 0c551fa..2b765aa 100644
--- a/cinera/cinera_config.c
+++ b/cinera/cinera_config.c
@@ -480,11 +480,21 @@ typedef struct
bool Hidden;
} medium;
+typedef enum
+{
+ AS_INITIAL,
+ AS_GIVEN_OR_NICKNAME,
+ AS_DOTTED_INITIAL_AND_SURNAME,
+ AS_NONE,
+ AS_COUNT
+} abbreviation_scheme;
+
typedef struct
{
string ID;
string Name;
// TODO(matt): string SortName;
+ string Abbreviations[AS_COUNT];
string QuoteUsername;
string Homepage;
_memory_book(support) Support;
@@ -979,6 +989,9 @@ InitTypeSpecs(void)
config_type_spec *Person = PushTypeSpec(&Result, IDENT_PERSON, FALSE);
PushTypeSpecField(Person, FT_STRING, IDENT_NAME, TRUE);
+ PushTypeSpecField(Person, FT_STRING, IDENT_ABBREV_INITIAL, TRUE);
+ PushTypeSpecField(Person, FT_STRING, IDENT_ABBREV_GIVEN_OR_NICKNAME, TRUE);
+ PushTypeSpecField(Person, FT_STRING, IDENT_ABBREV_DOTTED_INITIAL_AND_SURNAME, TRUE);
PushTypeSpecField(Person, FT_STRING, IDENT_HOMEPAGE, TRUE);
PushTypeSpecField(Person, FT_STRING, IDENT_QUOTE_USERNAME, TRUE);
PushTypeSpecField(Person, FT_SCOPE, IDENT_SUPPORT, FALSE);
@@ -3231,6 +3244,230 @@ PushSupport(config *C, resolution_errors *E, config_verifiers *V, person *P, sco
}
}
+void
+InitialSubstring(memory_book *Abbreviations,
+ string *Dest, string Src, int Extent, string PostInitialString)
+{
+ int SrcIndex = 0;
+ bool InQuote = FALSE;
+ string Initial;
+ int StepSize = 1;
+ if(Src.Base[SrcIndex] == '\"')
+ {
+ InQuote = !InQuote;
+ }
+ else
+ {
+ Initial = GetUTF8Character(Src.Base + SrcIndex, Extent - SrcIndex);
+ *Dest = ExtendStringInBook(Abbreviations, Initial);
+ *Dest = ExtendStringInBook(Abbreviations, PostInitialString);
+ StepSize = Initial.Length;
+ }
+ SrcIndex += StepSize;
+
+ for(; SrcIndex < Extent; SrcIndex += StepSize)
+ {
+ StepSize = 1;
+ switch(Src.Base[SrcIndex])
+ {
+ case ' ':
+ {
+ if(!InQuote
+ && SrcIndex + 1 < Extent && Src.Base[SrcIndex + 1] != '\"')
+ {
+ Initial = GetUTF8Character(Src.Base + SrcIndex + 1, Extent - SrcIndex - 1);
+ *Dest = ExtendStringInBook(Abbreviations, Initial);
+ *Dest = ExtendStringInBook(Abbreviations, PostInitialString);
+ StepSize = Initial.Length;
+ }
+ } break;
+ case '\"':
+ {
+ InQuote = !InQuote;
+ } break;
+ }
+ }
+}
+
+string
+InitialString(memory_book *Abbreviations, string Src)
+{
+ ResetPen(Abbreviations);
+ string Result = {};
+ InitialSubstring(Abbreviations, &Result, Src, Src.Length, Wrap0(""));
+ return Result;
+}
+
+string
+GetQuotedOrFirstSubstring(string Src)
+{
+ string Result;
+
+ string QuotedSubstring = {};
+ string FirstSubstring = Src;
+ bool GotFirstSubstring = FALSE;
+ bool InQuote = FALSE;
+
+ for(int SrcIndex = 0; SrcIndex < Src.Length && !QuotedSubstring.Length; ++SrcIndex)
+ {
+ switch(Src.Base[SrcIndex])
+ {
+ case ' ':
+ {
+ if(!InQuote && !GotFirstSubstring)
+ {
+ FirstSubstring.Base = Src.Base;
+ FirstSubstring.Length = SrcIndex;
+ GotFirstSubstring = TRUE;
+ }
+ } break;
+ case '\"':
+ {
+ if(!InQuote)
+ {
+ if(SrcIndex + 1 < Src.Length)
+ {
+ QuotedSubstring.Base = Src.Base + SrcIndex + 1;
+ }
+ }
+ else
+ {
+ QuotedSubstring.Length = SrcIndex - (QuotedSubstring.Base - Src.Base);
+ }
+ InQuote = !InQuote;
+ } break;
+ }
+ }
+
+ Result = QuotedSubstring.Length ? QuotedSubstring : FirstSubstring;
+ return Result;
+}
+
+string
+StripQuotedStringStart(string S)
+{
+ string Result = S;
+ if(Result.Length > 0 && Result.Base[0] == '\"')
+ {
+ ++Result.Base;
+ --Result.Length;
+ while(Result.Length > 0 && Result.Base[0] != '\"')
+ {
+ ++Result.Base;
+ --Result.Length;
+ }
+ Assert(Result.Length > 0);
+ ++Result.Base;
+ --Result.Length;
+ }
+ return Result;
+}
+
+string
+StripQuotedStringEnd(string S)
+{
+ string Result = S;
+ if(Result.Length > 0 && Result.Base[Result.Length - 1] == '\"')
+ {
+ --Result.Length;
+ while(Result.Length > 0 && Result.Base[Result.Length - 1] != '\"')
+ {
+ --Result.Length;
+ }
+ Assert(Result.Length > 0);
+ --Result.Length;
+ }
+ return Result;
+}
+
+bool
+IsLower(char C)
+{
+ return C >= 'a' && C <= 'z';
+}
+
+string
+DottedInitialAndGetSurname(memory_book *Abbreviations, string Src)
+{
+ ResetPen(Abbreviations);
+ string Result = {};
+ bool GotSurnameBase = FALSE;
+ string WorkingSrc = Src;
+
+ WorkingSrc = StripQuotedStringStart(WorkingSrc);
+ WorkingSrc = StripQuotedStringEnd(WorkingSrc);
+ WorkingSrc = TrimWhitespace(WorkingSrc);
+
+ int PossibleSurnameBase = WorkingSrc.Length - 1;
+ int SurnameBase = PossibleSurnameBase;
+
+ for(; PossibleSurnameBase > 0; --PossibleSurnameBase)
+ {
+ char Prev = WorkingSrc.Base[PossibleSurnameBase - 1];
+ if(Prev == ' ')
+ {
+ if(!GotSurnameBase)
+ {
+ SurnameBase = PossibleSurnameBase;
+ }
+ else if(IsLower(WorkingSrc.Base[PossibleSurnameBase]))
+ {
+ SurnameBase = PossibleSurnameBase;
+ }
+ else
+ {
+ break;
+ }
+ GotSurnameBase = TRUE;
+ }
+ else if(Prev == '\"')
+ {
+ break;
+ }
+ }
+
+ if(!GotSurnameBase)
+ {
+ SurnameBase = PossibleSurnameBase;
+ }
+
+ if(SurnameBase > 0 && WorkingSrc.Base[SurnameBase] == ' ' && SurnameBase < WorkingSrc.Length)
+ {
+ ++SurnameBase;
+ }
+
+ string Surname = Wrap0i_(WorkingSrc.Base + SurnameBase, WorkingSrc.Length - SurnameBase);
+
+ if(SurnameBase > 0)
+ {
+ InitialSubstring(Abbreviations, &Result, WorkingSrc, SurnameBase, Wrap0(". "));
+ }
+
+ Result = ExtendStringInBook(Abbreviations, Surname);
+ return Result;
+}
+
+void
+AbbreviateName(config *C, person *P)
+{
+ if(P->Abbreviations[AS_INITIAL].Length == 0)
+ {
+ P->Abbreviations[AS_INITIAL] = InitialString(&C->ResolvedVariables, P->Name);
+ }
+
+ if(P->Abbreviations[AS_GIVEN_OR_NICKNAME].Length == 0)
+ {
+ P->Abbreviations[AS_GIVEN_OR_NICKNAME] = GetQuotedOrFirstSubstring(P->Name);
+ }
+
+ if(P->Abbreviations[AS_DOTTED_INITIAL_AND_SURNAME].Length == 0)
+ {
+ P->Abbreviations[AS_DOTTED_INITIAL_AND_SURNAME] = DottedInitialAndGetSurname(&C->ResolvedVariables, P->Name);
+ }
+
+ P->Abbreviations[AS_NONE] = P->Name;
+}
+
void
PushPersonOntoConfig(config *C, resolution_errors *E, config_verifiers *V, scope_tree *PersonTree)
{
@@ -3238,12 +3475,30 @@ PushPersonOntoConfig(config *C, resolution_errors *E, config_verifiers *V, scope
//PrintScopeTree(PersonTree);
person *This = MakeSpaceInBook(&C->Person);
This->ID = ResolveString(C, E, PersonTree, &PersonTree->ID, FALSE);
+ bool NamingError = FALSE;
for(int i = 0; i < PersonTree->Pairs.ItemCount; ++i)
{
config_pair *Pair = GetPlaceInBook(&PersonTree->Pairs, i);
if(IDENT_NAME == Pair->Key)
{
This->Name = ResolveString(C, E, PersonTree, Pair, FALSE);
+ int QuotemarkCount = StringContainsXOfChar(This->Name, '\"');
+ if(QuotemarkCount == 1)
+ {
+ string Filepath = Wrap0(Pair->Position.Filename);
+ ConfigErrorField(&Filepath, Pair->Position.LineNumber, S_ERROR, IDENT_NAME,
+ "contains unpaired quotation mark: ", &This->Name);
+ PushError(E, S_ERROR, 0, Pair->Key);
+ NamingError = TRUE;
+ }
+ else if(QuotemarkCount > 2)
+ {
+ string Filepath = Wrap0(Pair->Position.Filename);
+ ConfigErrorField(&Filepath, Pair->Position.LineNumber, S_ERROR, IDENT_NAME,
+ "contains more than one pair of quotation marks: ", &This->Name);
+ PushError(E, S_ERROR, 0, Pair->Key);
+ NamingError = TRUE;
+ }
}
else if(IDENT_HOMEPAGE == Pair->Key)
{
@@ -3255,6 +3510,20 @@ PushPersonOntoConfig(config *C, resolution_errors *E, config_verifiers *V, scope
}
}
+ if(This->Name.Length == 0)
+ {
+ string Filepath = Wrap0(PersonTree->ID.Position.Filename);
+ ConfigErrorUnsetFieldOf(&Filepath, PersonTree->ID.Position.LineNumber,
+ IDENT_NAME, IDENT_PERSON, This->ID);
+ PushError(E, S_ERROR, 0, IDENT_NAME);
+ NamingError = TRUE;
+ }
+
+ if(!NamingError)
+ {
+ AbbreviateName(C, This);
+ }
+
if(This->QuoteUsername.Length == 0)
{
This->QuoteUsername = This->ID;
@@ -4113,6 +4382,9 @@ GetRowsRequiredForPersonInfo(typography *T, person *P)
uint8_t RowsRequired = 0;
if(P->Name.Length > 0) { ++RowsRequired; }
+ if(P->Abbreviations[AS_INITIAL].Length > 0) { ++RowsRequired; }
+ if(P->Abbreviations[AS_GIVEN_OR_NICKNAME].Length > 0) { ++RowsRequired; }
+ if(P->Abbreviations[AS_DOTTED_INITIAL_AND_SURNAME].Length > 0) { ++RowsRequired; }
if(P->Homepage.Length > 0) { ++RowsRequired; }
for(int i = 0; i < P->Support.ItemCount; ++i)
{
@@ -4150,6 +4422,27 @@ PrintPerson(person *P, typography *Typography)
--RowsRequired;
}
+ if(P->Abbreviations[AS_INITIAL].Length > 0)
+ {
+ fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
+ config_pair AbbrevInitial = { .Key = IDENT_ABBREV_INITIAL, .String = P->Abbreviations[AS_INITIAL], .Type = PT_STRING }; PrintPair(&AbbrevInitial, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
+ --RowsRequired;
+ }
+
+ if(P->Abbreviations[AS_GIVEN_OR_NICKNAME].Length > 0)
+ {
+ fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
+ config_pair AbbrevGivenOrNickname = { .Key = IDENT_ABBREV_GIVEN_OR_NICKNAME, .String = P->Abbreviations[AS_GIVEN_OR_NICKNAME], .Type = PT_STRING }; PrintPair(&AbbrevGivenOrNickname, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
+ --RowsRequired;
+ }
+
+ if(P->Abbreviations[AS_DOTTED_INITIAL_AND_SURNAME].Length > 0)
+ {
+ fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
+ config_pair AbbrevDottedInitialAndSurname = { .Key = IDENT_ABBREV_DOTTED_INITIAL_AND_SURNAME, .String = P->Abbreviations[AS_DOTTED_INITIAL_AND_SURNAME], .Type = PT_STRING }; PrintPair(&AbbrevDottedInitialAndSurname, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
+ --RowsRequired;
+ }
+
if(P->Homepage.Length > 0)
{
fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);