/// <summary> /// Creates a usage description for the command associated with the provided /// 'parameterObject'. /// <para> /// The usage description is either the one provided with /// the 'UsageAttribute' or a generic description created from the known /// parameter attributes. /// </para> /// <para> /// The result string is supposed to be rendered on the command line. /// </para> /// </summary> /// <param name="parameterObject"></param> /// <param name="screenWidth"></param> /// <returns>The resulting string</returns> public virtual string CreateUsage(ParameterBase parameterObject, int screenWidth = 80) { string result; string usage; result = String.Empty; result += CreateUsageHeader(screenWidth); result += "Usage:\r\n\r\n"; UsageAttribute? usageAttribute = (UsageAttribute?)parameterObject.GetType().GetCustomAttribute(typeof(UsageAttribute)); // // If a usage description is provided in the command attributes return that description. // if ((usageAttribute != null) && !String.IsNullOrWhiteSpace(usageAttribute.Usage)) { usage = usageAttribute.Usage; } // // Create a usage description from the known parameter attributes. // else { usage = parameterObject.CommandName + " "; usage += "[" + parameterObject.HelpIndicatorList.First() + "] "; usage += "[" + parameterObject.VersionIndicatorList.First() + "] "; foreach (var metaInfo in parameterObject.PropertyMetaInfoList) { if (metaInfo.IsMandatory) { usage += metaInfo.Name + "=" + "<" + metaInfo.Type + "> "; } else { usage += "[" + metaInfo.Name + "=" + "<" + metaInfo.Type + ">" + "] "; } } } List<string> lines = CreateWrappedLines(usage, screenWidth, 0); return result + String.Join("\r\n", lines); }
const char Asterisk = '*'; // * // ************************************************************************ // IDisplayHelper implementation START // ************************************************************************ /// <summary> /// Creates the help screen for the parameter object provided in argument /// 'parameterObject'. /// <para> /// The line length of the resulting help text will match with value provide in argument 'screenWidth' /// as long a the value is greater than the minimum screen line length. Otherwise the minimum screen /// line length will be used. /// </para> /// <para> /// The result string is supposed to be rendered on the command line. /// </para> /// </summary> /// <param name="parameterObject"></param> /// <param name="screenWidth"></param> /// <returns>The resulting string</returns> public virtual string CreateHelp(ParameterBase parameterObject, int screenWidth = 80) { string result; int longestArgumentLength; int longestTypeLength; int longestDefaultLength; string help; List<string> helpLines; result = string.Empty; longestArgumentLength = 0; if (parameterObject == null) { return result; } HelpAttribute? helpAttribute = (HelpAttribute?)parameterObject.GetType().GetCustomAttribute(typeof(HelpAttribute)); // // If a help text is provided in the command attributes show that text first. // if ((helpAttribute != null) && !String.IsNullOrWhiteSpace(helpAttribute.Help)) { help = helpAttribute.Help; } else { help = string.Empty; } if (parameterObject.PropertyMetaInfoList.Count == 0) { result = "The current parameter object has no parameter property!"; } else { longestArgumentLength = parameterObject.PropertyMetaInfoList.Max(item => item.Name.Length); longestTypeLength = parameterObject.PropertyMetaInfoList.Max(item => item.Type.Length); longestDefaultLength = parameterObject.PropertyMetaInfoList.Max(item => (item.DefaultValue?.ToString()?.Length ?? 0)); longestArgumentLength = Math.Max(longestArgumentLength, "[Parameter]".Length); // [Parameter] = 11 characters min longestTypeLength = Math.Max(longestTypeLength, "[Type]".Length); // [Type] = 6 characters min longestDefaultLength = Math.Max(longestDefaultLength, "[Default]".Length); // [Default] = 9 characters min // // Expand the screen width if there isn't at least 20 characters left for the description. // Minimum length for the help screen is 11 + 6 + 9 + 20 for parameter, type default and description // plus additional 15 characters for spaces and borders. That is 61 characters minimum. // if((longestArgumentLength + longestTypeLength + longestDefaultLength + 20) > screenWidth) { screenWidth = (longestArgumentLength + longestTypeLength + longestDefaultLength + 20); } if(!String.IsNullOrWhiteSpace(help)) { // // Format the help text from the help attribute. // helpLines = CreateWrappedLines(help, screenWidth, leadingSpaces:0, keepEmptyLines:true); result += "\r\n" + String.Join("\r\n", helpLines) + "\r\n\r\n"; } result += CreateHelpHeader(screenWidth); result += CreateHelpTop(screenWidth, longestArgumentLength, longestTypeLength, longestDefaultLength); result += CreateHelpAndVersionArgumentHelpLines(parameterObject.HelpIndicatorList.First(), "Shows the help screen. (This screen).", screenWidth, longestArgumentLength, longestTypeLength, longestDefaultLength); result += CreateHelpSeparatorLine(screenWidth, longestArgumentLength, longestTypeLength, longestDefaultLength); result += CreateHelpAndVersionArgumentHelpLines(parameterObject.VersionIndicatorList.First(), "Shows the command version number if available or an empty string. (Nothing)", screenWidth, longestArgumentLength, longestTypeLength, longestDefaultLength); result += CreateHelpSeparatorLine(screenWidth, longestArgumentLength, longestTypeLength, longestDefaultLength); for (int index = 0; index < parameterObject.PropertyMetaInfoList.Count; index++) { result += CreateHelpLines(parameterObject.PropertyMetaInfoList[index], screenWidth, longestArgumentLength, longestTypeLength, longestDefaultLength); if (index < parameterObject.PropertyMetaInfoList.Count - 1) { result += CreateHelpSeparatorLine(screenWidth, longestArgumentLength, longestTypeLength, longestDefaultLength); } } result += CreateHelpBottom(screenWidth, longestArgumentLength, longestTypeLength, longestDefaultLength); } result += "\r\n\r\n"; result += CreateUsage(parameterObject); return result; }