Skip to Content
Nextra 4.0 is released 🎉

Formatter

The formatter module handles formatting of help messages. It provides functions that accept a set of option definitions and render help messages in ANSI format. The messages produced by the formatter can also be customized via message configuration.

Help message

Internally, the help message consists of ANSI strings, which may contain escape sequences and are meant to be printed in a terminal. Visually, it is composed of the following kinds of content:

  • entry - the text lines pertaining to a single option
  • item - a piece of information in an option’s description
  • group - a set of entries corresponding to an option group
  • section - like the section of a document (may be a collection of groups)
  • column - a horizontal division (as formed by a vertical ruler) across all entries in a section

This is better illustrated by the figure below:

Lorem ipsum dolor sit amet, consectetur adipiscingelit, sed do eiusmod tempor incididunt ut labore etdolore magna aliqua.[entry][item][group][column][section]

To generate a help message, you must call the format function. It accepts the following parameters:

  • options - the option definitions (required)
  • sections - a list of help sections to include in the message (optional, defaults to a single groups section)
  • filter - an option filter to select a subset of options (optional, defaults to none)
  • progName - a program name to display in usage sections (optional, defaults to none)

It returns a ANSI message with the formatted sections.

Help columns

Every option definition produces a help entry in its respective group in the help message. Furthermore, the whole set of entries across all groups in a section is split into “columns” (not to be confused with terminal columns), each containing a different kind 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. The positional marker, if present, is appended to this list.

Name slots

Depending on the column alignment setting, each option name may reserve a “slot” in the respective position in this column. The width of a name slot will be the length of the longest name in that slot, among all options. A null value can be specified in order to skip the corresponding slot.

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

-f, -ff, --flag

Note how the absent name produced whitespace between its neighbors.

Empty strings will also be suppressed, but names containing spaces will appear unquoted.

Parameter column

This column is rendered according to the following rules:

  • if the option is niladic, do nothing
  • else, if it contains an example value, render this value
  • otherwise
    • if it contains a parameter name, render this name
    • else, render the word 'param'
    • and enclose the result in angle brackets '<>' (if this was not already the case)
  • and, if it requires inline parameters, prepend an equals sign '='
  • and, if it accepts multiple parameters, append an ellipsis '...'
  • and, if it can be specified without parameters and is not a nameless positional argument, enclose the result 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.

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 optional 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 feeds to insert before the section (defaults to 0 for the first section, 1 for others)
  • noWrap - true to disable wrapping of text properties (defaults to false)
⚠️

When noWrap is set, be careful with inline styles present in text properties, as they will appear in redirected command outputs and will not be affected by the NO_COLOR and related variables. (See ANSI message.)

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, usage instructions, afterword, copyright notice or external references. In addition to the common properties, it has the following optional properties:

  • text - the section content (defaults to none)
  • 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|--no-flag)] [[(-b|--boolean) <param>] (-sc|--strChoice) 'one'] [(-sr|--strRegex) <my str>] [(-nr|--numRange) <my num>] [(-nc|--numChoice)=1] [(-sa|--strArray) [<param>...]] [(-na|--numArray) [<param>...]] [[(--strArrayLimit|--)] ['one'...]] [--numArrayUnique ['1,2'...]]

In addition to the common properties, a usage section has the following optional 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 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 at this time. For that purpose, you have to create different usages. (The reason is that it 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 optional 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)
  • layout - an object with column layout settings for the section (see below)
  • items - the order of help items to be shown in option descriptions (defaults to all items)
  • useEnv - whether option names should be replaced by environment variable names (defaults to false)

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

đź’ˇ

The useEnv property is useful when you want to create a dedicated section for environment variables.

Column layout

The layout of a groups section can be configured via a partial HelpColumnsLayout object containing three optional properties: names, param and descr. They can be used to customize the layout of the corresponding help column, and is applied to all help entries in the section. They are objects with the following optional settings:

  • align - text alignment for the column (may be one of 'left' or 'right', defaults to 'left')
  • indent - level of indentation for the column (must be non-negative if absolute is true, defaults to 2)
  • breaks - number of line feeds 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)

Here’s a graph showing a single help entry with default layout in a terminal with 80-character width:

And here’s a layout where we eliminate the names indentation, hide the param column and merge with descr:

Column alignment

The names.align property supports an additional value 'slot', meaning that each name receives a “slot” in the column, and the name is left-aligned within that slot. See name slots for more information. This value will be ignored if param.align is set to 'merge' or if param.hidden is true and descr.align is set to 'merge' (see below).

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, both the indent and breaks properties are ignored.

Note that merging a column is not the same as using zero indentation. Indentation is always relative to the end of the previous column, which depends on the length of the longest text in that column, across all entries. On the other hand, merging implies having no additional space between text in both columns.

Layout example

An example can better illustrate the effect of some of the layout settings. Suppose we have:

{ 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 } }

Below is an extract of a help message produced with the above configuration:

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

Help items

The items property of a groups section specifies the kinds of help items that should be displayed in option descriptions, and in which order. It is an array whose values can be one of the enumerators from HelpItem. The default is to print all items in the order listed in the enumerator type.

đź’ˇ

You might want to use this to limit the amount of information in the help message.

Option filter

The filter parameter to the format function lists patterns that indicate which options should be rendered in the help message. It matches options’ names, synopsis and environment data sources. 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.

Last updated on