public ExtendFormatEventArgs(CustomFormatInfo formatInfo) { FormatInfo = formatInfo; }
/// <summary> /// Determines what to do when an Invalid Selector is found. /// /// Returns True if we should just continue; False if we should skip this item. /// </summary> private bool OnInvalidSelector(string format, CustomFormatInfo info, PlaceholderInfo placeholder) { string invalidSelector = format.Substring(placeholder.selectorStart, placeholder.selectorLength); string message; switch (InvalidSelectorAction) { case ErrorAction.ThrowError: // Let's give a detailed description of the error: message = FormatEx( ("Invalid Format String.\\n" + ("Could not evaluate \"{0}\": \"{1}\" is not a member of {2}.\\n" + ("The error occurs at position {3} of the following format string:\\n" + "{4}"))), invalidSelector, info.Selector, info.CurrentType, placeholder.placeholderStart, format); throw new ArgumentException(message, invalidSelector); case ErrorAction.OutputErrorInResult: // Let's put the placeholder back, // along with the error. // Example: {Person.Name.ABC} becomes {Person.Name.ABC:(Error: "ABC" is not a member of String)} message = ("{" + (FormatEx("{0}:(Error: \"{1}\" is not a member of {2})", invalidSelector, info.Selector, info.CurrentType) + "}")); info.WriteError(message, placeholder); return false; case ErrorAction.Ignore: // Allow formatting to continue! break; } return true; }
/// <summary> /// Does the actual work. /// </summary> internal void FormatExInternal(CustomFormatInfo info) { if (info.Current == null && info.Arguments.Length >= 1) { info.Current = info.Arguments[0]; } // We need to store the Format and the Current items and keep them in this context string format = info.Format; object current = info.Current; // ' Here is the regular expression to use for parsing the Format string: // Static R As New Regex( _ // "{ ([0-9A-Za-z_.\[\]()]*) (?: : ( (?: (?<open>{) | (?<nest-open>}) | [^{}]+ )*? ) (?(open)(?!)) )? }" _ // , RegexOptions.IgnorePatternWhitespace Or RegexOptions.Compiled) // { ( Selectors ) (Optnl : { Nested } or Format ) } int lastAppendedIndex = 0; PlaceholderInfo placeholder = null; while (NextPlaceholder(format, lastAppendedIndex, format.Length, ref placeholder)) { // Write the text in-between placeholders: info.WriteRegularText(format, lastAppendedIndex, (placeholder.placeholderStart - lastAppendedIndex)); lastAppendedIndex = placeholder.placeholderStart + placeholder.placeholderLength; // Evaluate the source by evaluating each argSelector: info.Current = current; // Restore the current scope //bool isFirstSelector = true; // TODO: Remove this variable if it never gets used again int selectorIndex = -1; foreach (string selector in placeholder.selectors) { selectorIndex++; info.SetSelector(selector, selectorIndex); // Raise the ExtendCustomSource event to allow custom source evaluation: OnExtendSourceEvent(new ExtendSourceEventArgs(info)); // Make sure that the selector has been handled: if (!info.Handled) { break; } //isFirstSelector = false; } // Handle errors: if (!info.Handled) { // If the ExtendCustomSource event wasn't handled, // then the Selector could not be evaluated. if (!OnInvalidSelector(format, info, placeholder)) { continue; } } string argFormat = format.Substring(placeholder.formatStart, placeholder.formatLength); info.SetFormat(argFormat, placeholder.hasNested); try { // Raise the ExtendCustomFormat event to allow custom formatting: OnExtendFormatEvent(new ExtendFormatEventArgs(info)); } catch (Exception ex) { // Handle errors: OnInvalidFormat(format, info, placeholder, ex); } } // Write the substring between the last bracket and the end of the string: info.WriteRegularText(format, lastAppendedIndex, (format.Length - lastAppendedIndex)); }
/// <summary> /// Determines what to do when an Invalid Selector is found. /// </summary> private void OnInvalidFormat(string format, CustomFormatInfo info, PlaceholderInfo placeholder, Exception ex) { string selector = format.Substring(placeholder.selectorStart, placeholder.selectorLength); string invalidFormat = format.Substring(placeholder.formatStart, placeholder.formatLength); string errorMessage = ex.Message; if (ex is FormatException) { errorMessage = FormatEx("\"{0}\" is not a valid format specifier for {1}", invalidFormat, info.CurrentType); } string message; switch (InvalidFormatAction) { case ErrorAction.ThrowError: // Let's give a detailed description of the error: message = FormatEx( ("Invalid Format String.\\n" + ("Could not evaluate {{0}} because {1}.\\n" + ("The error occurs at position {2} of the following format string:\\n" + "{3}"))), selector, errorMessage, placeholder.placeholderStart, format); throw new ArgumentException(message, invalidFormat, ex); case ErrorAction.OutputErrorInResult: // Let's put the placeholder back, // along with the error. // Example: {Person.Birthday:x} becomes {Person.Birthday:(Error: "x" is an invalid format specifier)} message = ("{" + (FormatEx("{0}:(Error: {1})", selector, errorMessage) + "}")); info.WriteError(message, placeholder); break; case ErrorAction.Ignore: // Allow formatting to continue! break; } }
public ExtendFormatEventArgs(CustomFormatInfo formatInfo) { FormatInfo = formatInfo; }