@@ -624,12 +624,18 @@ private static Func<int, ConsoleColoredString> getHelpGenerator(Type type, Func<
624624 }
625625 helpString . Add ( ConsoleColoredString . NewLine ) ;
626626
627- // Word-wrap the documentation for the command (if any)
627+ // Output the documentation for the command (if any)
628628 var doc = getDocumentation ( type , helpProcessor ) ;
629- foreach ( var line in doc . WordWrap ( wrapWidth ) )
629+ if ( doc . Any ( d => d . Length > 0 ) )
630630 {
631- helpString . Add ( line ) ;
632- helpString . Add ( ConsoleColoredString . NewLine ) ;
631+ var docTable = new TextTable { MaxWidth = wrapWidth , ColumnSpacing = fmtOpt . ColumnSpacing , RowSpacing = fmtOpt . RowSpacing , StretchLastCell = true } ;
632+ foreach ( var row in doc )
633+ {
634+ for ( var x = 0 ; x < row . Length ; x ++ )
635+ docTable . AddCell ( row [ x ] ) ;
636+ docTable . FinishRow ( ) ;
637+ }
638+ helpString . Add ( docTable . ToColoredString ( ) ) ;
633639 }
634640
635641
@@ -650,7 +656,7 @@ private static Func<int, ConsoleColoredString> getHelpGenerator(Type type, Func<
650656 var section = field . GetCustomAttribute < SectionAttribute > ( ) ;
651657 if ( curTable == null || lastMandatory != mandatory || section != null )
652658 {
653- curTable = new TextTable { MaxWidth = wrapWidth - fmtOpt . LeftMargin , ColumnSpacing = fmtOpt . ColumnSpacing , RowSpacing = fmtOpt . RowSpacing , LeftMargin = fmtOpt . LeftMargin } ;
659+ curTable = new TextTable { MaxWidth = wrapWidth - fmtOpt . LeftMargin , ColumnSpacing = fmtOpt . ColumnSpacing , RowSpacing = fmtOpt . RowSpacing , LeftMargin = fmtOpt . LeftMargin , StretchLastCell = true } ;
654660 paramsTables . Add ( ( section ? . Heading ?? $ "{ ( mandatory ? "Required" : "Optional" ) } parameters:", curTable ) ) ;
655661 curRow = 0 ;
656662 }
@@ -689,18 +695,22 @@ private static bool createParameterHelpRow(ref int row, TextTable table, FieldIn
689695 var anyCommandsWithSuboptions = false ;
690696 var cmdName = "<" . Color ( CmdLineColor . FieldBrackets ) + field . Name . Color ( CmdLineColor . Field ) + ">" . Color ( CmdLineColor . FieldBrackets ) ;
691697
698+ int plonkDocumentation ( int startCol , int startRow , ConsoleColoredString [ ] [ ] docs , bool min1 )
699+ {
700+ for ( var r = 0 ; r < docs . Length ; r ++ )
701+ for ( var c = 0 ; c < docs [ r ] . Length ; c ++ )
702+ table . SetCell ( startCol + c , startRow + r , docs [ r ] [ c ] ) ;
703+ return Math . Max ( docs . Length , min1 ? 1 : 0 ) ;
704+ }
705+
692706 if ( field . FieldType . IsEnum )
693707 {
694708 // ### ENUM fields, positional
695709 if ( positional )
696710 {
697711 var topRow = row ;
698712 var doc = getDocumentation ( field , helpProcessor ) ;
699- if ( doc . Length > 0 || field . FieldType . GetFields ( BindingFlags . Static | BindingFlags . Public ) . All ( el => el . IsDefined < UndocumentedAttribute > ( ) || ! el . GetCustomAttributes < CommandNameAttribute > ( ) . Any ( ) ) )
700- {
701- table . SetCell ( 2 , row , doc , colSpan : 4 ) ;
702- row ++ ;
703- }
713+ row += plonkDocumentation ( 2 , row , doc , min1 : false ) ;
704714 foreach ( var el in field . FieldType . GetFields ( BindingFlags . Static | BindingFlags . Public ) )
705715 {
706716 if ( el . IsDefined < UndocumentedAttribute > ( ) )
@@ -710,32 +720,31 @@ private static bool createParameterHelpRow(ref int row, TextTable table, FieldIn
710720 continue ;
711721 table . SetCell ( 2 , row , attr . Names . Where ( n => n . Length <= 2 ) . Select ( s => s . Color ( CmdLineColor . EnumValue ) ) . JoinColoredString ( ", " ) , noWrap : true ) ;
712722 table . SetCell ( 3 , row , attr . Names . Where ( n => n . Length > 2 ) . Select ( s => s . Color ( CmdLineColor . EnumValue ) ) . JoinColoredString ( Environment . NewLine ) , noWrap : true ) ;
713- table . SetCell ( 4 , row , getDocumentation ( el , helpProcessor ) , colSpan : 2 ) ;
714- row ++ ;
723+ row += plonkDocumentation ( 4 , row , getDocumentation ( el , helpProcessor ) , min1 : true ) ;
715724 }
725+ if ( row == topRow )
726+ row ++ ;
716727 table . SetCell ( 0 , topRow , cmdName , noWrap : true , colSpan : 2 , rowSpan : row - topRow ) ;
717728 }
718729 // ### ENUM fields, “-x foo” scheme
719730 else if ( field . IsDefined < OptionAttribute > ( ) )
720731 {
721732 var topRow = row ;
722- row ++ ;
733+ row += plonkDocumentation ( 2 , row , getDocumentation ( field , helpProcessor ) , min1 : false ) ;
723734 foreach ( var el in field . FieldType . GetFields ( BindingFlags . Static | BindingFlags . Public ) . Where ( e => ! e . IsDefined < UndocumentedAttribute > ( ) ) )
724735 {
725736 var attr = el . GetCustomAttributes < CommandNameAttribute > ( ) . FirstOrDefault ( ) ;
726737 if ( attr == null ) // skip the default value
727738 continue ;
728739 table . SetCell ( 3 , row , attr . Names . Where ( n => n . Length <= 2 ) . Select ( s => s . Color ( CmdLineColor . EnumValue ) ) . JoinColoredString ( ", " ) , noWrap : true ) ;
729740 table . SetCell ( 4 , row , attr . Names . Where ( n => n . Length > 2 ) . Select ( s => s . Color ( CmdLineColor . EnumValue ) ) . JoinColoredString ( Environment . NewLine ) , noWrap : true ) ;
730- table . SetCell ( 5 , row , getDocumentation ( el , helpProcessor ) ) ;
731- row ++ ;
741+ row += plonkDocumentation ( 5 , row , getDocumentation ( el , helpProcessor ) , min1 : true ) ;
732742 }
733- if ( row == topRow + 1 )
734- throw new InvalidOperationException ( $ "Enum type { field . FieldType . DeclaringType . FullName } . { field . FieldType } has no values (apart from default value for field { field . DeclaringType . FullName } . { field . Name } )." ) ;
743+ if ( row == topRow )
744+ row ++ ;
735745 table . SetCell ( 0 , topRow , field . GetOrderedOptionAttributeNames ( ) . Where ( o => ! o . StartsWith ( "--" ) ) . OrderBy ( cmd => cmd . Length ) . Select ( cmd => cmd . Color ( CmdLineColor . Option ) ) . JoinColoredString ( ", " ) , noWrap : true , rowSpan : row - topRow ) ;
736746 table . SetCell ( 1 , topRow , field . GetOrderedOptionAttributeNames ( ) . Where ( o => o . StartsWith ( "--" ) ) . OrderBy ( cmd => cmd . Length ) . Select ( cmd => cmd . Color ( CmdLineColor . Option ) ) . JoinColoredString ( Environment . NewLine ) , noWrap : true , rowSpan : row - topRow ) ;
737- table . SetCell ( 2 , topRow , getDocumentation ( field , helpProcessor ) , colSpan : 4 ) ;
738- table . SetCell ( 2 , topRow + 1 , cmdName , noWrap : true , rowSpan : row - topRow - 1 ) ;
747+ table . SetCell ( 2 , topRow , cmdName , noWrap : true , rowSpan : row - topRow - 1 ) ;
739748 }
740749 // ### ENUM fields, “-x” scheme
741750 else
@@ -744,8 +753,7 @@ private static bool createParameterHelpRow(ref int row, TextTable table, FieldIn
744753 {
745754 table . SetCell ( 0 , row , el . GetOrderedOptionAttributeNames ( ) . Where ( o => ! o . StartsWith ( "--" ) ) . OrderBy ( cmd => cmd . Length ) . Select ( cmd => cmd . Color ( CmdLineColor . Option ) ) . JoinColoredString ( ", " ) , noWrap : true ) ;
746755 table . SetCell ( 1 , row , el . GetOrderedOptionAttributeNames ( ) . Where ( o => o . StartsWith ( "--" ) ) . OrderBy ( cmd => cmd . Length ) . Select ( cmd => cmd . Color ( CmdLineColor . Option ) ) . JoinColoredString ( Environment . NewLine ) , noWrap : true ) ;
747- table . SetCell ( 2 , row , getDocumentation ( el , helpProcessor ) , colSpan : 4 ) ;
748- row ++ ;
756+ row += plonkDocumentation ( 2 , row , getDocumentation ( el , helpProcessor ) , min1 : true ) ;
749757 }
750758 }
751759 }
@@ -765,25 +773,22 @@ private static bool createParameterHelpRow(ref int row, TextTable table, FieldIn
765773 var names = ty . GetCustomAttributes < CommandNameAttribute > ( ) . First ( ) . Names ;
766774 table . SetCell ( 2 , row , names . Where ( n => n . Length <= 2 ) . Select ( n => n . Color ( CmdLineColor . Command ) + asterisk ) . JoinColoredString ( ", " ) , noWrap : true ) ;
767775 table . SetCell ( 3 , row , names . Where ( n => n . Length > 2 ) . Select ( n => n . Color ( CmdLineColor . Command ) + asterisk ) . JoinColoredString ( Environment . NewLine ) , noWrap : true ) ;
768- table . SetCell ( 4 , row , getDocumentation ( ty , helpProcessor ) , colSpan : 2 ) ;
769- row ++ ;
776+ row += plonkDocumentation ( 4 , row , getDocumentation ( ty , helpProcessor ) , min1 : true ) ;
770777 }
771778 table . SetCell ( 0 , origRow , cmdName , colSpan : 2 , rowSpan : row - origRow , noWrap : true ) ;
772779 }
773780 // ### All other positional parameters
774781 else if ( positional )
775782 {
776783 table . SetCell ( 0 , row , cmdName , noWrap : true , colSpan : 2 ) ;
777- table . SetCell ( 2 , row , getDocumentation ( field , helpProcessor ) , colSpan : 4 ) ;
778- row ++ ;
784+ row += plonkDocumentation ( 2 , row , getDocumentation ( field , helpProcessor ) , min1 : true ) ;
779785 }
780786 // ### All other non-positional parameters
781787 else
782788 {
783789 table . SetCell ( 0 , row , field . GetOrderedOptionAttributeNames ( ) . Where ( o => ! o . StartsWith ( "--" ) ) . OrderBy ( cmd => cmd . Length ) . Select ( cmd => cmd . Color ( CmdLineColor . Option ) ) . JoinColoredString ( ", " ) , noWrap : true ) ;
784790 table . SetCell ( 1 , row , field . GetOrderedOptionAttributeNames ( ) . Where ( o => o . StartsWith ( "--" ) ) . OrderBy ( cmd => cmd . Length ) . Select ( cmd => cmd . Color ( CmdLineColor . Option ) ) . JoinColoredString ( Environment . NewLine ) , noWrap : true ) ;
785- table . SetCell ( 2 , row , getDocumentation ( field , helpProcessor ) , colSpan : 4 ) ;
786- row ++ ;
791+ row += plonkDocumentation ( 2 , row , getDocumentation ( field , helpProcessor ) , min1 : true ) ;
787792 }
788793 return anyCommandsWithSuboptions ;
789794 }
@@ -806,8 +811,8 @@ private static void getFieldsForHelp(Type type, out List<FieldInfo> optionalOpti
806811 }
807812 }
808813
809- private static ConsoleColoredString getDocumentation ( MemberInfo member , Func < ConsoleColoredString , ConsoleColoredString > helpProcessor ) =>
810- member . IsDefined < DocumentationAttribute > ( ) ? helpProcessor ( member . GetCustomAttributes < DocumentationAttribute > ( ) . Select ( d => d . Text ?? "" ) . First ( ) ) : "" ;
814+ private static ConsoleColoredString [ ] [ ] getDocumentation ( MemberInfo member , Func < ConsoleColoredString , ConsoleColoredString > helpProcessor ) =>
815+ member . GetCustomAttributes < DocumentationAttribute > ( ) . Select ( doc => doc . Texts . Select ( helpProcessor ) . ToArray ( ) ?? [ ] ) . ToArray ( ) ;
811816
812817 #region Post-build step check
813818
@@ -1049,12 +1054,12 @@ private static void checkDocumentation(IPostBuildReporter rep, MemberInfo member
10491054 return ;
10501055
10511056 var attr = member . GetCustomAttributes < DocumentationAttribute > ( ) . FirstOrDefault ( ) ;
1052- ConsoleColoredString toCheck = null ;
1057+ ConsoleColoredString [ ] toCheck = null ;
10531058 if ( attr != null )
10541059 {
10551060 try
10561061 {
1057- toCheck = attr . Text ; // this property can throw the first time it's accessed
1062+ toCheck = attr . Texts ; // this property can throw the first time it's accessed
10581063 }
10591064 catch ( Exception e )
10601065 {
0 commit comments