Documentation
Formatter

Formatter

The HelpFormatter is a base class for components that handle formatting of help messages. Concrete classes that extend it can be instantiated with a validator instance and provide methods to format help messages.

Help format

There are four concrete classes of formatter, each one handling a different help message format:

  • AnsiFormatter - formats help messages in ANSI format, i.e., they may contain escape sequences and are meant to be printed in a terminal
  • JsonFormatter - formats help messages in JSON format, i.e., they are meant to be consumed by introspection tools and other applications
  • CsvFormatter - formats help messages in CSV format, i.e., they are meant to be transformed and exchanged with other applications
  • MdFormatter - formats help messages in Markdown format, i.e., they are meant to be processed by documentation tools, or to be versioned with the code
⚠️

Everything contained in this page relates to the AnsiFormatter class.

Help message

Internally, the help message is a list of terminal strings that may contain control sequences and are meant to be printed in a terminal. Visually, it can be divided into the following pieces of content:

  • section - a group of text lines, like the section of a document
  • entry - the lines corresponding to an option definition
  • item - a single bit of information in an option's description
  • group - a set of entries corresponding to an option group
  • column - a horizontal division (as formed by a vertical ruler) across all entries of all groups

There are two main ways of obtaining help messages, as described below.

Grouped help

The format method returns the help message of an option group. It accepts a single optional parameter: the name of the group. If not provided, the default group is used, which corresponds to the set of options that did not explicitly declare a group in their definition.

Sectioned help

The sections method returns a help message that includes help sections, as will be explained later in this page. It accepts two parameters:

  • sections - a list of HelpSections to include in the help message
  • progName - an optional program name to display in usage sections

Help entries

Each option definition results in a help entry being included under its respective group in the help message. An entry is divided into "columns" (not to be confused with terminal columns), each containing a piece of information, as described below.

Names column

This column contains the options' names separated by commas. The names are listed in the same order as was specified in the names attribute.

Name slots

Depending on the column's alignment configuration, each option name may reserve a "slot" in the respective position in this column. The length of a name slot will be the length of the largest name in that slot, among all options. Empty strings or nulls can be specified in order to skip a slot.

For example, if an option's names are '-f', '-ff', '' and '--flag', the resulting entry might be formatted as:

-f, -ff      --flag

Note how the empty string produced whitespace between its neighbors, and the commas were suppressed.

Parameter column

This column contains either the option's type, the example value or the parameter name. It is rendered in the following way:

  • if the option:
    • is niladic, it is omitted
    • contains an example value, this value is used
    • is a command option, it is rendered with a standalone ellipsis '...'
    • is a function option, type is replaced by the word param
    • does not have a parameter name containing an opening angle bracket '<', it is enclosed in angle brackets '<>'
    • requires inline parameters, it is prefixed with an equals sign '='
    • accepts more than one parameter, it is suffixed with an ellipsis '...'
    • can be specified without parameters (i.e., has a fallback value), it is enclosed in square brackets '[]'

The result might be something like =<param> or [<param>...].

Description column

The last column contains the option description and is composed of help items, which are explained later in this page.

Help sections

Sections are a convenient way to organize the help content. There are three kinds of help sections: text, usage and groups. They are explained below.

Common properties

All help sections share a set of properties:

  • title - the section heading or the default option group heading (defaults to none)
  • style - the style of the section heading or option group headings (defaults to tf.bold)
  • breaks - the number of line breaks to insert before the section (defaults to 0 for the first section, else 2)
  • noWrap - true to disable wrapping of provided texts (defaults to false)

When noWrap is set, inline styles may still be used in text properties, but the latter will not be formatted according to the text formatting rules.

All headings are separated from their content by two line feeds, unless extra spacing is provided in heading texts. For the sake of simplicity, there is no way to configure this behavior.

Text section

A text section can be used to write many kinds of content, such as an introductory text, CLI usage instructions, afterword, copyright notice or external references. In addition to the common properties, it has the following properties:

  • text - the section content
  • indent - the level of indentation of the section content (defaults to 0)

Usage section

The usage text is a concise representation of a program's command-line. Here is an example:

demo.js [(-h|--help)] [(-v|--version)] # get help
demo.js hello ... # execute the hello command
demo.js [(-f|--flag|--no-flag)]
        [(-b|--boolean) <boolean>]
        [(-s|--stringRegex) <my str>]
        [(-n|--numberRange) <my num>]
        [(-se|--stringEnum) 'one']
        [(-ne|--numberEnum) 1]
        [(-ss|--strings) [<strings>]]
        [(-ns|--numbers) <numbers>...]
        [[(--stringsEnum|--)] 'one' 'two']
        [--numbersEnum '1,2']

In addition to the common properties, a usage section has the following properties:

  • indent - the level of indentation of the section content (defaults to 0)
  • filter - a list of option keys to include or exclude (defaults to including all options)
  • exclude - whether the filter should exclude (defaults to false)
  • required - a list of options that should be considered always required
  • requires - a map of option keys to required options (defaults to none)
  • comment - a commentary to append to the usage (defaults to none)
💡

The filter can be used to create multiple usages of the same command, with different options. In the case of an inclusion filter, options are listed in the same order specified in the filter.

Option dependencies

The requires property is equivalent to an adjacency list, except that each source option can only reference a single target. Mutually dependent options are supported. The following table lists some examples that illustrate how this works. Suppose we have options A, B and C. Then:

DependenciesUsageIf C is always required
A requires B requires C[[[A] B] C][[A] B] C
A and B require each other[A B] [C][A B] C
A requires B requires C requires A[A B C]A B C
A and C require B[[A] B [C]][A] B C
A requires B; C requires A[[A [C]] B]A C B

Mutual exclusivity and multi-targeting are not supported. For that purpose, you have to create different usages. (The reason is that this is difficult to implement. We sincerely apologize.)

Groups section

A groups section is a collection of option groups and their help entries. In addition to the common properties, it has the following properties:

  • filter - a list of group names to include or exclude (defaults to including all groups)
  • exclude - whether the filter should exclude (defaults to false)
💡

In the case of an inclusion filter, groups are listed in the same order specified in the filter.

Formatter configuration

In addition to the validator instance, the formatter constructor accepts a FormatterConfig object that can be used to customize the format of help entries in option groups. This configuration will apply to all entries. Its properties are optional and are described below.

Help columns

The names, param and descr properties specify settings for each help column. They are objects with the following optional properties:

  • align - text alignment for the column (may be one of 'left' or 'right', defaults to 'left')
  • indent - level of indentation for the column (non-negative if absolute is true, defaults to 2)
  • breaks - number of line breaks to insert before each entry in the column (defaults to 0)
  • hidden - whether the column should be hidden (defaults to false)
  • absolute - whether the indentation level should be relative to the beginning of the line instead of the end of the previous column (not available for the names column, defaults to false)

The names.align property supports an additional value 'slot', which means that each name receives a "slot" in the column, and the name is left-aligned within that slot. See name slots for more information.

The param.align and descr.align properties support an additional value 'merge', which instructs the formatter to merge the contents of the column with the previous one. This is useful, for instance, if you want option parameters to be inlined with option names. When using this value, the indent and breaks properties are ignored.

An example can better illustrate the effect of some of these settings. Suppose we have the following configuration:

{
  names: {
    align: 'slot',  // assign a slot to each option name
  },
  param: {
    breaks: 1,      // break option parameters
    indent: -10,    // recede 10 terminal columns from the end of the names column
  },
  descr: {
    align: 'right', // align option descriptions to the right
    breaks: 1,      // break option descriptions
    indent: 20,     // indent 20 terminal columns...
    absolute: true, // from the beginning of the line
  }
}

The following is an extract of a help message produced with these settings:

  -ne,   --numberEnum
            1
                             A number option. Values must be one of {1, 2}.
  -ns,   --numbers
            <numbers>...
                      A numbers option. Accepts multiple parameters. Values
                    must be in the range [0, Infinity]. Defaults to [1, 2].

Help items

The items property specifies the kinds of items that should be displayed in option descriptions, and in what order. It is an array whose values can be one of the enumerators from HelpItem:

The default is to render all items in the order listed above.

💡

You might want to use this to limit the amount of information, especially if you intend to export the help message in either CSV or Markdown format. In these formats, a table column is rendered for each help item, regardless of whether it has information or not.

Help phrases

The phrases property specifies the phrases to be used for each kind of help item. It has the following optional properties, whose keys are enumerators from HelpItem:

  • desc - '%t'
  • negationNames - 'Can be negated with %o.'
  • separator - 'Values are delimited by (%s|%r).'
  • paramCount - 'Accepts (multiple|%n|at most %n|at least %n|between %n) parameters.'
  • positional - 'Accepts positional parameters(| that may be preceded by %o).'
  • append - 'May be specified multiple times.'
  • trim - 'Values will be trimmed.'
  • case - 'Values will be converted to (lowercase|uppercase).'
  • conv - 'Values will be converted with Math.%t.'
  • enums - 'Values must be one of {(%s|%n)}.'
  • regex - 'Values must match the regex %r.'
  • range - 'Values must be in the range [%n].'
  • unique - 'Duplicate values will be removed.'
  • limit - 'Element count is limited to %n.'
  • requires - 'Requires %p.'
  • required - 'Always required.'
  • default - 'Defaults to (%b|%s|%n|[%s]|[%n]|%v).'
  • deprecated - 'Deprecated for %t.'
  • link - 'Refer to %u for details.'
  • envVar - 'Can be specified through the %o environment variable.'
  • requiredIf - 'Required if %p.'
  • clusterLetters - 'Can be clustered with %s.'
  • fallback - 'Falls back to (%b|%s|%n|[%s]|[%n]|%v) if specified without parameter.'
  • useNested - 'Uses the next argument as the name of a nested command.'
  • useFormat - 'Uses the next argument as the name of a help format.'
  • useFilter - 'Uses the remaining arguments as option filter.'
  • inline - '(Disallows|Requires) inline parameters.'

Phrases are formatted according to text formatting rules. They are only rendered in help messages in ANSI format.

Format specifiers

Help phrases may have format specifiers prefixed with a percent sign %, which get replaced with a value. The following table lists the available specifiers for each kind of help item, along with a description of the corresponding value:

ErrorSpecifiers
desc%t = the option's synopsis
negationNames%o = the negation names
separator%s/%r = the parameter separator
paramCount%n = the parameter count
positional%o = the positional marker
conv%t = the math function
enums%s/%n = the enumerated values
regex%r = the regular expression
range%n = the numeric range
limit%n = the count limit
requires%p = the requirements
default%b/%s/%n/%v = the default value
deprecated%t = the deprecation notice
link%u = the hyperlink
envVar%o = the variable name
requiredIf%p = the requirements
clusterLetters%s = the cluster letters
fallback%b/%s/%n/%v = the fallback value

Option filter

The filter property specifies a list of patterns to select the options that will be rendered in the help message. The filter matches options' names, synopsis and environment variable names. If multiple patterns are provided, any matched one will suffice to include an option in the message.

💡

This is inherently different from what a text search utility like grep would produce. The formatter will render the whole help entry of options matching the given patterns, not just the matching lines.

Help styles

Help messages are styled using the set of error styles from the validator configuration, except that they may get overridden by (or combined with) an option's display styles, if present.

💡

Whitespace around help entries is not styled. For that purpose, you may need to tweak your terminal settings.

Footnotes

  1. polyadic means that the option accepts more than one parameter, but the parameter count is not variable