void HourParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(info.Hour);
void MinuteParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(info.Minute);
void StageNumberParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(info.Vessel?.currentStage);
void CustomParser(StringBuilder result, CommonInfo info) => ParseIntoBuilder(result, Historian.Instance.GetConfiguration().CustomText.Replace("<Custom>", "")); // avoid recurssion.
void HeadingParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(FlightGlobals.ship_heading.ToString("F1"));
void ListFontsParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(string.Join(", ", OSFonts));
void TouristsListParser(StringBuilder result, CommonInfo info) => GenericCrewParser(result, info.Vessel, isList: true, isShort: false, traits: new string[] { "Tourist" }, traitColours: info.TraitColours);
void VesselCostParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(info.Vessel?.parts.Sum(p => p.partInfo.cost));
void CrewListParser(StringBuilder result, CommonInfo info) => GenericCrewParser(result, info.Vessel, isList: true, isShort: false, traits: allTraits, traitColours: info.TraitColours);
void EngineersParser(StringBuilder result, CommonInfo info) => GenericCrewParser(result, info.Vessel, isList: false, isShort: false, traits: new string[] { "Engineer" }, traitColours: info.TraitColours);
void UTParser(StringBuilder result, CommonInfo info) => result.Append($"Y{info.Year + 1}, D{(info.Day):D3}, {info.Hour}:{info.Minute:D2}:{info.Second:D2}");
void RealDateParser(StringBuilder result, CommonInfo info) => result.Append(DateTime.Now.ToString(info.DateFormat));
void CustomParser(StringBuilder result, CommonInfo info) => ParseIntoBuilder(result, Historian.Instance.GetConfiguration().CustomText.Replace("<Custom>", "")); // avoid recurssion. void DateFormatParser(StringBuilder result, CommonInfo info) => result.Append(info.DateFormat);
void SecondParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(info.Second);
void VesselTypeParser(StringBuilder result, CommonInfo info) => result.Append(info.Vessel?.vesselType);
void VesselParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(info.Vessel?.vesselName);
void NewLineParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(Environment.NewLine);
void PartCountParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(info.Vessel?.parts.Count);
void UTParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(KSPUtil.dateTimeFormatter.PrintDateCompact(info.UT, true, true));
void TouristsListParser(StringBuilder result, CommonInfo info, string[] args) => GenericCrewParser(result, info.Vessel, isList: true, isShort: false, showLabel: false, all: false, traitsFilter: new string[] { "Tourist" }, traitsInfo: info.Traits);
void YearParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(info.Year + ((isKerbincalendar) ? baseYear + 1 : baseYear));
void VesselTypeParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(info.Vessel?.vesselType.displayDescription());
void DayParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(info.Day);
void LastActionParser(StringBuilder result, CommonInfo info, string[] args) => result.Append(Historian.Instance.LastAction);
protected void ParseIntoBuilder(StringBuilder result, string text) { // get common data sources var ut = Planetarium.GetUniversalTime(); //var time = isKerbincalendar // ? dateFormatter.GetKerbinDateFromUT((int)ut) // : dateFormatter.GetEarthDateFromUT((int)ut); var vessel = FlightGlobals.ActiveVessel; var orbit = vessel?.GetOrbit(); var target = vessel?.targetObject; var info = new CommonInfo { Vessel = vessel, Orbit = orbit, Time = new SplitDateTimeValue(ut).TimeParts, UT = ut, Target = target, TraitColours = new string[] { pilotColor, engineerColor, scientistColor, touristColor }, DateFormat = dateFormat }; // scan template text string for parameter tokens int i = 0, tokenLen; while (i < text.Length) { char ch = text[i]; if (ch == '<') { // possible token found tokenLen = GetTokenLength(text, i); if (tokenLen >= 0) { // extract token var token = text.Substring(i + 1, tokenLen); // check if recognised if (parsers.ContainsKey(token)) { // run parser for matching token - each action must append to the stringbuilder parsers[token](result, info); } else { // token not found copy as literal result.Append("<"); result.Append(token); result.Append(">"); } // include < and > in counted tokenlength tokenLen += 2; } else { // no end token found treat as literal tokenLen = 1; result.Append(ch); } } else { // literal tokenLen = 1; result.Append(ch); } i += tokenLen; } }