Skip to content

Commit

Permalink
Merge branch '1379-HelpProvider-colors-should-be-configurable' of htt…
Browse files Browse the repository at this point in the history
…ps://github.com/FrankRay78/spectre.console into 1379-HelpProvider-colors-should-be-configurable
  • Loading branch information
FrankRay78 committed Jan 15, 2024
2 parents cf503c3 + f679444 commit 10fa323
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 124 deletions.
30 changes: 30 additions & 0 deletions docs/input/cli/command-help.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,36 @@ The help is also context aware and tailored depending on what has been specified

`HelpProvider` is the `Spectre.Console` class responsible for determining context and preparing the help text to write to the console. It is an implementation of the public interface `IHelpProvider`.

## Styling the help text

Basic styling is applied to the generated help text by default, however this is configurable.

There are three different themes shipped with Spectre.Console, namely `Default`, `BoldHeadings`, `None`.

You can explicitly set the theme when configuring a CommandApp, for example:

```csharp
config.Settings.HelpProviderStyles = HelpProviderStyle.BoldHeadings;
```

Implied by the name, `HelpProviderStyle.None` doesn't include any styles and is a good choice for accessibility.

A custom theme can also be defined and applied, in a similar way how the HelpProviderStyle factories do it.

```csharp
HelpProviderStyle styles = default(HelpProviderStyle);

styles.Description.Header.Markup = "yellow";
styles.Usage.Header.Markup = "yellow";
styles.Usage.CurrentCommand.Markup = "underline";
styles.Usage.Command.Markup = "aqua";

config.Settings.HelpProviderStyles = styles;

```

See [Markup](../markup) for information about the use of markup in Spectre.Console, and [Styles](xref:styles) for a listing of supported styles.

## Custom help providers

Whilst it shouldn't be common place to implement your own help provider, it is however possible.
Expand Down
4 changes: 4 additions & 0 deletions examples/Cli/Help/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Spectre.Console.Cli;
using Spectre.Console.Cli.Help;

namespace Help;

Expand All @@ -12,6 +13,9 @@ public static int Main(string[] args)
{
// Register the custom help provider
config.SetHelpProvider(new CustomHelpProvider(config.Settings));

// Render an unstyled help text for maximum accessibility
config.Settings.HelpProviderStyles = HelpProviderStyle.None;
});

return app.Run(args);
Expand Down
14 changes: 1 addition & 13 deletions src/Spectre.Console.Cli/Help/HelpProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,6 @@ public class HelpProvider : IHelpProvider
/// </remarks>
protected virtual bool RenderMarkupInline { get; }

/// <summary>
/// Gets a value indicating whether to ignore styling when rendering the help text.
/// </summary>
/// <remarks>
/// Black and white help text will be rendered when <c>true</c>, ensuring maximum accessibility.
/// </remarks>
/// <value>
/// <c>true</c> if styling should be ignored; otherwise, <c>false</c>.
/// </value>
protected virtual bool IgnoreStyling { get; }

private sealed class HelpArgument
{
public string Name { get; }
Expand Down Expand Up @@ -114,7 +103,7 @@ public static IReadOnlyList<HelpOption> Get(ICommandInfo? command, HelpProviderR

internal Composer NewComposer()
{
return new Composer(RenderMarkupInline, IgnoreStyling);
return new Composer(RenderMarkupInline);
}

/// <summary>
Expand All @@ -127,7 +116,6 @@ public HelpProvider(ICommandAppSettings settings)
this.MaximumIndirectExamples = settings.MaximumIndirectExamples;
this.TrimTrailingPeriod = settings.TrimTrailingPeriod;
this.RenderMarkupInline = settings.RenderMarkupInline;
this.IgnoreStyling = settings.IgnoreStyling;
this.helpStyles = settings.HelpProviderStyles;

resources = new HelpProviderResources(settings.Culture);
Expand Down
50 changes: 25 additions & 25 deletions src/Spectre.Console.Cli/Help/HelpProviderStyles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static HelpProviderStyle Default
{
get
{
HelpProviderStyle styles;
HelpProviderStyle styles = default(HelpProviderStyle);

styles.Description.Header.Markup = "yellow";
styles.Usage.Header.Markup = "yellow";
Expand Down Expand Up @@ -70,38 +70,38 @@ public static HelpProviderStyle Default
}

/// <summary>
/// Gets the unstyled HelpProvider styles.
/// Gets the bold heading HelpProvider styles.
/// </summary>
public static HelpProviderStyle None
public static HelpProviderStyle BoldHeadings
{
get
{
HelpProviderStyle styles;

styles.Description.Header.Markup = string.Empty;
styles.Usage.Header.Markup = string.Empty;
styles.Usage.CurrentCommand.Markup = string.Empty;
styles.Usage.Command.Markup = string.Empty;
styles.Usage.Options.Markup = string.Empty;
styles.Usage.RequiredArgument.Markup = string.Empty;
styles.Usage.OptionalArgument.Markup = string.Empty;
styles.Examples.Header.Markup = string.Empty;
styles.Examples.Arguments.Markup = string.Empty;
styles.Arguments.Header.Markup = string.Empty;
styles.Arguments.RequiredArgument.Markup = string.Empty;
styles.Arguments.OptionalArgument.Markup = string.Empty;
styles.Commands.Header.Markup = string.Empty;
styles.Commands.ChildCommand.Markup = string.Empty;
styles.Commands.RequiredArgument.Markup = string.Empty;
styles.Options.Header.Markup = string.Empty;
styles.Options.DefaultValueHeader.Markup = string.Empty;
styles.Options.DefaultValue.Markup = string.Empty;
styles.Options.RequiredOption.Markup = string.Empty;
styles.Options.OptionalOption.Markup = string.Empty;
HelpProviderStyle styles = default(HelpProviderStyle);

styles.Description.Header.Markup = "bold";
styles.Usage.Header.Markup = "bold";
styles.Examples.Header.Markup = "bold";
styles.Arguments.Header.Markup = "bold";
styles.Commands.Header.Markup = "bold";
styles.Options.Header.Markup = "bold";

return styles;
}
}

/// <summary>
/// Gets the unstyled HelpProvider styles.
/// </summary>
/// <remarks>
/// Black and white help text will be rendered to ensure maximum accessibility.
/// </remarks>
public static HelpProviderStyle None
{
get
{
return default(HelpProviderStyle);
}
}
}

#pragma warning disable SA1600 // XML documentation for public members
Expand Down
11 changes: 0 additions & 11 deletions src/Spectre.Console.Cli/ICommandAppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,6 @@ public interface ICommandAppSettings
/// </remarks>
bool RenderMarkupInline { get; set; }

/// <summary>
/// Gets or sets a value indicating whether to ignore styling when rendering the help text.
/// </summary>
/// <remarks>
/// Black and white help text will be rendered when <c>true</c>, ensuring maximum accessibility.
/// </remarks>
/// <value>
/// <c>true</c> if styling should be ignored; otherwise, <c>false</c>.
/// </value>
bool IgnoreStyling { get; set; }

/// <summary>
/// Gets or sets the styles to used when rendering the help text.
/// </summary>
Expand Down
55 changes: 9 additions & 46 deletions src/Spectre.Console.Cli/Internal/Composer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using static System.Net.Mime.MediaTypeNames;

namespace Spectre.Console.Cli;

internal sealed class Composer : IRenderable
Expand All @@ -11,21 +9,15 @@ internal sealed class Composer : IRenderable
/// </summary>
private readonly bool renderMarkup = false;

/// <summary>
/// Whether to ignore styling when rendering the content.
/// </summary>
private readonly bool ignoreStyling = false;

public Composer()
{
content = new StringBuilder();
}

public Composer(bool renderMarkup, bool ignoreStyling)
public Composer(bool renderMarkup)
: this()
{
this.renderMarkup = renderMarkup;
this.ignoreStyling = ignoreStyling;
}

public Composer Text(string text)
Expand All @@ -36,39 +28,18 @@ public Composer Text(string text)

public Composer Style(string style, string text)
{
if (ignoreStyling)
{
Text(text);
}
else
{
if (string.IsNullOrEmpty(style))
{
Text(text);
}
else
{
content.Append('[').Append(style).Append(']');
content.Append(text.EscapeMarkup());
content.Append("[/]");
}
}
content.Append('[').Append(style).Append(']');
content.Append(text.EscapeMarkup());
content.Append("[/]");

return this;
}

public Composer Style(string style, Action<Composer> action)
{
if (ignoreStyling)
{
action(this);
}
else
{
content.Append('[').Append(style).Append(']');
action(this);
content.Append("[/]");
}
content.Append('[').Append(style).Append(']');
action(this);
content.Append("[/]");

return this;
}
Expand Down Expand Up @@ -134,11 +105,7 @@ public Composer Join(string separator, IEnumerable<Composer> composers)

public Measurement Measure(RenderOptions options, int maxWidth)
{
if (ignoreStyling)
{
return ((IRenderable)new Paragraph(content.ToString())).Measure(options, maxWidth);
}
else if (renderMarkup)
if (renderMarkup)
{
return ((IRenderable)new Paragraph(content.ToString())).Measure(options, maxWidth);
}
Expand All @@ -150,11 +117,7 @@ public Measurement Measure(RenderOptions options, int maxWidth)

public IEnumerable<Segment> Render(RenderOptions options, int maxWidth)
{
if (ignoreStyling)
{
return ((IRenderable)new Paragraph(content.ToString())).Render(options, maxWidth);
}
else if (renderMarkup)
if (renderMarkup)
{
return ((IRenderable)new Paragraph(content.ToString())).Render(options, maxWidth);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ internal sealed class CommandAppSettings : ICommandAppSettings
public bool ValidateExamples { get; set; }
public bool TrimTrailingPeriod { get; set; }
public bool RenderMarkupInline { get; set; }
public bool IgnoreStyling { get; set; }
public HelpProviderStyle HelpProviderStyles { get; set; }
public bool StrictParsing { get; set; }
public bool ConvertFlagsToRemainingArguments { get; set; }
Expand All @@ -33,9 +32,7 @@ public CommandAppSettings(ITypeRegistrar registrar)
MaximumIndirectExamples = 5;
TrimTrailingPeriod = true;
RenderMarkupInline = false;
IgnoreStyling = false;
//HelpProviderStyles = HelpProviderStyle.Default;
HelpProviderStyles = HelpProviderStyle.None;
HelpProviderStyles = HelpProviderStyle.Default;
ConvertFlagsToRemainingArguments = false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Spectre.Console/Internal/Text/Markup/MarkupParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static Paragraph Parse(string text, Style? style = null)

if (token.Kind == MarkupTokenKind.Open)
{
var parsedStyle = StyleParser.Parse(token.Value);
var parsedStyle = string.IsNullOrEmpty(token.Value) ? Style.Plain : StyleParser.Parse(token.Value);
stack.Push(parsedStyle);
}
else if (token.Kind == MarkupTokenKind.Close)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[bold]DESCRIPTION:[/]
The lion command.

[bold]USAGE:[/]
myapp []<TEETH>[/] [][[LEGS]][/] [][[OPTIONS]][/] [][[COMMAND]][/]

[bold]EXAMPLES:[/]
myapp []20 --alive[/]

[bold]ARGUMENTS:[/]
[]<TEETH>[/] The number of teeth the lion has
[][[LEGS]][/] The number of legs

[bold]OPTIONS:[/]
[]DEFAULT[/]
-h, --help Prints help information
-v, --version Prints version information
-a, --alive Indicates whether or not the animal is alive
-n, --name []<VALUE>[/]
--agility []<VALUE>[/] []10[/] The agility between 0 and 100
-c []<CHILDREN>[/] The number of children the lion has
-d []<DAY>[/] []Monday[/], []Thursday[/] The days the lion goes hunting
-w, --weight [][[WEIGHT]][/] The weight of the lion, in kgs

[bold]COMMANDS:[/]
[]giraffe[/] []<LENGTH>[/] The giraffe command
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
DESCRIPTION:
[]DESCRIPTION:[/]
The lion command.

USAGE:
myapp <TEETH> [LEGS] [OPTIONS] [COMMAND]
[]USAGE:[/]
myapp []<TEETH>[/] [][[LEGS]][/] [][[OPTIONS]][/] [][[COMMAND]][/]

EXAMPLES:
myapp 20 --alive
[]EXAMPLES:[/]
myapp []20 --alive[/]

ARGUMENTS:
<TEETH> The number of teeth the lion has
[LEGS] The number of legs
[]ARGUMENTS:[/]
[]<TEETH>[/] The number of teeth the lion has
[][[LEGS]][/] The number of legs

OPTIONS:
DEFAULT
-h, --help Prints help information
-v, --version Prints version information
-a, --alive Indicates whether or not the animal is alive
-n, --name <VALUE>
--agility <VALUE> 10 The agility between 0 and 100
-c <CHILDREN> The number of children the lion has
-d <DAY> Monday, Thursday The days the lion goes hunting
-w, --weight [WEIGHT] The weight of the lion, in kgs
[]OPTIONS:[/]
[]DEFAULT[/]
-h, --help Prints help information
-v, --version Prints version information
-a, --alive Indicates whether or not the animal is alive
-n, --name []<VALUE>[/]
--agility []<VALUE>[/] []10[/] The agility between 0 and 100
-c []<CHILDREN>[/] The number of children the lion has
-d []<DAY>[/] []Monday[/], []Thursday[/] The days the lion goes hunting
-w, --weight [][[WEIGHT]][/] The weight of the lion, in kgs

COMMANDS:
giraffe <LENGTH> The giraffe command
[]COMMANDS:[/]
[]giraffe[/] []<LENGTH>[/] The giraffe command
Loading

0 comments on commit 10fa323

Please sign in to comment.