@@ -677,7 +677,7 @@ internal static void AddLine(StringBuilder builder, string value, int maximumLen
677677 value = value . TrimEnd ( ) ;
678678
679679 builder . AppendWhen ( builder . Length > 0 , Environment . NewLine ) ;
680- builder . Append ( WrapAndIndentText ( value , 0 , maximumLength ) ) ;
680+ builder . Append ( TextWrapper . WrapAndIndentText ( value , 0 , maximumLength ) ) ;
681681 }
682682
683683 private IEnumerable < Specification > GetSpecificationsFromType ( Type type )
@@ -806,7 +806,7 @@ private HelpText AddOption(string requiredWord, int maxLength, Specification spe
806806
807807 //note that we need to indent trim the start of the string because it's going to be
808808 //appended to an existing line that is as long as the indent-level
809- var indented = WrapAndIndentText ( optionHelpText , maxLength + TotalOptionPadding , widthOfHelpText ) . TrimStart ( ) ;
809+ var indented = TextWrapper . WrapAndIndentText ( optionHelpText , maxLength + TotalOptionPadding , widthOfHelpText ) . TrimStart ( ) ;
810810
811811 optionsHelp
812812 . Append ( indented )
@@ -949,111 +949,9 @@ private static string FormatDefaultValue<T>(T value)
949949 : string . Empty ;
950950 }
951951
952- /// <summary>
953- /// Splits a string into a words and performs wrapping while also preserving line-breaks and sub-indentation
954- /// </summary>
955- /// <param name="input">The string to wrap</param>
956- /// <param name="indentLevel">The amount of padding at the start of each string</param>
957- /// <param name="columnWidth">The number of characters we can use for text</param>
958- /// <remarks>
959- /// The use of "width" is slightly confusing in other methods. In this method, the columnWidth
960- /// parameter is the number of characters we can use for text regardless of the indent level.
961- /// For example, if columnWidth is 10 and indentLevel is 2, the input
962- /// "a string for wrapping 01234567890123"
963- /// would return
964- /// " a string" + newline +
965- /// " for" + newline +
966- /// " wrapping" + newline +
967- /// " 0123456789" + newline +
968- /// " 0123"
969- /// </remarks>
970- /// <returns>A string that has been word-wrapped with padding on each line to indent it</returns>
971- private static string WrapAndIndentText ( string input , int indentLevel , int columnWidth )
972- {
973- //start by splitting at newlines and then reinserting the newline as a separate word
974- //Note that on the input side, we can't assume the line-break style at run time so we have to
975- //be able to handle both. We cant use Environment.NewLine because that changes at
976- //_runtime_ and may not match the line-break style that was compiled in
977- var lines = input
978- . Replace ( "\r " , "" )
979- . Split ( new [ ] { '\n ' } , StringSplitOptions . None ) ;
980- var lineCount = lines . Length ;
981-
982- var tokens = lines
983- . Zip ( new string [ lineCount ] , ( a , _ ) => new string [ ] { a , Environment . NewLine } )
984- . SelectMany ( linePair=> linePair )
985- . Take ( lineCount * 2 - 1 ) ;
986-
987- //split into words
988- var words = tokens
989- . SelectMany ( l=> l . Split ( ' ' ) ) ;
990-
991- //create a list of individual indented lines
992- var wrappedLines = words
993- . Aggregate < string , List < StringBuilder > > (
994- new List < StringBuilder > ( ) ,
995- ( lineList , word ) => AddWordToLastLineOrCreateNewLineIfNecessary ( lineList , word , columnWidth )
996- )
997- . Select ( builder => indentLevel . Spaces ( ) + builder . ToString ( ) . TrimEnd ( ) ) ;
998-
999- //return the whole thing as a single string
1000- return string . Join ( Environment . NewLine , wrappedLines ) ;
1001- }
1002-
1003- /// <summary>
1004- /// When presented with a word, either append to the last line in the list or start a new line
1005- /// </summary>
1006- /// <param name="lines">A list of stringbuilders containing results so far</param>
1007- /// <param name="word">The individual word to append</param>
1008- /// <param name="columnWidth">The usable text space</param>
1009- /// <remarks>
1010- /// The 'word' can actually be an empty string or a linefeed. It's important to keep these -
1011- /// empty strings allow us to preserve indentation and extra spaces within a line and linefeeds
1012- /// allow us to honour the users formatting wishes when the pass in multi-line helptext.
1013- /// </remarks>
1014- /// <returns>The same list as is passed in</returns>
1015- private static List < StringBuilder > AddWordToLastLineOrCreateNewLineIfNecessary ( List < StringBuilder > lines , string word , int columnWidth )
1016- {
1017- if ( word == Environment . NewLine )
1018- {
1019- //A newline token just means advance to the next line.
1020- lines . Add ( new StringBuilder ( ) ) ;
1021- return lines ;
1022- }
1023- //The current indentLevel is based on the previous line.
1024- var previousLine = lines . LastOrDefault ( ) ? . ToString ( ) ?? string . Empty ;
1025- var currentIndentLevel = previousLine . Length - previousLine . TrimStart ( ) . Length ;
1026-
1027- var wouldWrap = ! lines . Any ( ) || previousLine . Length + word . Length > columnWidth ;
1028-
1029- if ( ! wouldWrap )
1030- {
1031- //The usual case is we just append the 'word' and a space to the current line
1032- //Note that trailing spaces will get removed later when we turn the line list
1033- //into a single string
1034- lines . Last ( ) . Append ( word + ' ' ) ;
1035- }
1036- else
1037- {
1038- //The 'while' here is to take account of the possibility of someone providing a word
1039- //which just can't fit in the current column. In that case we just split it at the
1040- //column end.
1041- //That's a rare case though - most of the time we'll succeed in a single pass without
1042- //having to split
1043- while ( word . Length > 0 )
1044- {
1045- var availableCharacters = Math . Min ( columnWidth - currentIndentLevel , word . Length ) ;
1046-
1047- var segmentToAdd = currentIndentLevel . Spaces ( ) +
1048- word . Substring ( 0 , availableCharacters ) + ' ' ;
1049-
1050- lines . Add ( new StringBuilder ( segmentToAdd ) ) ;
1051- word = word . Substring ( availableCharacters ) ;
1052- }
1053- }
1054- return lines ;
1055- }
1056-
952+
1057953
1058954 }
1059955}
956+
957+
0 commit comments