Documentation
Styles

Styles

The Style type is a string literal consisting of Select Graphic Rendition (SGR (opens in a new tab)) sequences. It can be used to customize the display of text in terminals that support it.

Styling attributes

The style function accepts a list of styling attributes and creates a Style that can be used in any part of the API that expects this type, or it can be embedded directly in text attributes, such as the synopsis and deprecation notice, help section texts, error phrases and help phrases.

Styles are cumulative, i.e., they can be combined with previous styles depending on the kind of styling attribute. For instance, if the style of an option's description is tf.bold and the style of number values is fg.yellow, then any number value (except those embedded in text attributes) that appears in the option description will be rendered in bold intensity with yellow foreground color.

In the next sections we present the various styling attributes available.

⚠️

Not all of the attributes are supported in every terminal, so you should experiment with them before committing your code.

Type faces

The tf enumeration declares text type faces that can be combined together. They are listed below.

Enabling attributes

  • bold - bold or increased intensity
  • faint - faint, decreased intensity, or dim
  • italic - italic
  • underlined - underlined
  • slowlyBlinking - slowly blinking
  • rapidlyBlinking - rapidly blinking
  • inverse - reverse video or inverse (flips foreground and background color)
  • invisible - invisible, concealed or hidden
  • crossedOut - crossed-out or strikethrough
  • doublyUnderlined - doubly underlined
  • proportionalSpacing - proportional spacing

Font-changing attributes

  • primaryFont - primary font
  • alternative[1-9] - alternative font 1 through 9
  • fraktur - black-letter font

Ideogram attributes

  • ideogramUnderline - ideogram underline or right side line
  • ideogramDoubleUnderline - ideogram double underline, or double line on the right side
  • ideogramOverline - ideogram overline or left side line
  • ideogramDoubleOverline - ideogram double overline, or double line on the left side
  • ideogramStressMarking - ideogram stress marking

Miscellaneous attributes

  • framed - framed
  • encircled - encircled
  • overlined - overlined
  • superscript - superscript
  • subscript - subscript

Resetting attributes

  • clear - resets any other preceding SGR attribute
  • notBoldOrFaint - normal intensity (neither bold nor faint)
  • notItalicNorFraktur - regular face (neither italic nor black-letter)
  • notUnderlined - not underlined
  • notBlinking - steady (not blinking)
  • notInverse - positive (not inverse)
  • notInvisible - visible (reveal, or not hidden)
  • notCrossedOut - not crossed out (no strikethrough)
  • notProportionalSpacing - disable proportional spacing
  • notFramedOrEncircled - neither framed nor encircled
  • notOverlined - not overlined
  • noIdeogram - no ideogram attributes
  • notSuperscriptOrSubscript - neither superscript nor subscript

Predefined text colors

The fg and bg enumerations declare predefined foreground and background colors, respectively. They both have the same colors, which are listed below.

  • default - the default color

Standard colors

  • black - black
  • red - red
  • green - green
  • yellow - yellow
  • blue - blue
  • magenta - magenta
  • cyan - cyan
  • white - white

High-intensity colors

  • brightBlack - bright black (gray)
  • brightRed - bright red
  • brightGreen - bright green
  • brightYellow - bright yellow
  • brightBlue - bright blue
  • brightMagenta - bright magenta
  • brightCyan - bright cyan
  • brightWhite - bright white

Extended text colors

In addition to predefined colors, there are three utility functions to get custom 8-bit colors:

  • fg8 - creates a foreground color from an 8-bit decimal value
  • bg8 - creates a background color from an 8-bit decimal value
  • ul8 - creates an underline color from an 8-bit decimal value

Underline styles

The ul constant holds the styles of underlined text:

  • none - no underline
  • single - single underline
  • double - double underline
  • curly - curly underline
  • dotted - dotted underline
  • dashed - dashed underline

Terminal strings

The TerminalString class is an internal component that handles the construction of strings that can be printed on a terminal. It has methods to split, append and wrap strings, with or without control sequences, and is used by the library in different places:

The main logic implemented in this class is divided into splitting and wrapping, as is explained in the next sections.

Text splitting

Text is split into paragraphs, list items and words using a combination of simple regular expressions. The features supported in text splitting are described below.

Format specifiers

During splitting, format specifiers prefixed with a percent sign % may be extracted from the text and processed by a formatting callback. This is used by the library in different places:

This particular feature is only available in phrases, not in text attributes of option definitions. Specifiers are meant to be replaced with a value (or values, in case of arrays). The available ones are:

  • b - a boolean value
  • s - a string value
  • n - a number value
  • r - a regular expression
  • o - an option name
  • v - an unknown value (enclosed in angle brackets, like the parameter column)
  • u - a URL hyperlink
  • t - a general text
  • p - a previously formatted string

If a phrase supports values, the specifier can be used to indicate where in the phrase to place the value. If a phrase has multiple alternatives (depending on the context), different texts may be specified separated by a vertical bar and grouped in parentheses, e.g. '(...|...)'. Specifiers may also end with a single digit that represents a predefined value in an error message or help item.

Inline styles

Text can contain inline styles. This applies as well to phrases as to text attributes, which the formatter splits into words before adding to the help message.

When splitting text, the terminal string will try its best to preserve styles. However, if you find some corner case that is not currently covered by our unit tests, please submit a bug report (opens in a new tab).

⚠️

Phrases can contain inline styles, but not in the same word as a format specifier. Otherwise, they will mess up the text wrapping. For example, the following phrase is not valid: `Requires ${style(tf.bold)}%p`. You must insert a space in-between.

Paragraphs and lists

Although markdown syntax is not currently supported, paragraphs and itemized/numbered lists are formatted similarly to how they would be in markdown. For example, the following text

A paragraph with
  single line breaks,  redundant  spacing  and:
    - itemized; or
  1. numbered lists
 
  Another paragraph

Would be rendered as:

A paragraph with single line breaks, redundant spacing and:
- itemized; or
1. numbered lists
 
Another paragraph

Text wrapping

Text is wrapped according to a configured width, i.e., the number of terminal columns by which to limit each line of text.

When a width of zero or undefined is provided (which may happen if the output is being redirected), the terminal string will avoid wrapping and will suppress some control sequences that would otherwise be used to render the text in a terminal.

The following features are supported in text wrapping.

Indentation level

A terminal string optionally has an indentation level, i.e., the starting column of the text content, relative to the first terminal column.

When wrapping text to the desired width, the terminal string will attempt to respect this setting, but if the desired width does not accommodate the length of the largest word while respecting the string's indentation level, it will instead wrap lines relatively to the first terminal column.

Text alignment

A terminal string has an optional flag that indicates whether the text should be aligned to the terminal's right boundary when being wrapped. This feature is used by the formatter in the help message's description column.

Messages

There are different kinds of text content that an application might print in a terminal. We call them "messages" and provide a specific class for each kind of message that the library may produce. For convenience, all message classes have a toString method and a message property, both of which can be used to obtain a normal string.

💡

All messages produced by the library are instances of one of the classes described below. So you can check the kind of a captured message through instanceof.

User-facing messages

User-facing messages are meant to be consumed by humans. Each message class of this kind uses a default terminal width to render the resulting string when calling toString or using the message property. They are described below.

ANSI message

The AnsiMessage is a base class that wraps a list of terminal strings.

The default terminal width used by this class is the value of the 'FORCE_WIDTH' environment variable (if present), or the columns property of the standard output stream (i.e., process.stdout). Therefore, this kind of message should be printed with console.log or equivalent.

When redirecting the output of a command (e.g., writing to a file or piping to another command), the associated stream will not have a columns property, thus defaulting to zero.

This class provides an additional wrap method to get a normal string. It accepts two optional parameters:

  • width - the desired terminal width (or zero to avoid wrapping)
  • emitStyles - whether styles should be emitted

The default value of emitStyles depends on a few environment variables:

  • FORCE_COLOR - force emission of styles regardless of the terminal width
  • NO_COLOR - force omission of styles regardless of the terminal width
  • TERM - set to 'dumb' to achieve the same behavior as NO_COLOR

Generally, you should not alter the returned string after being wrapped, as this will mess up the disposition of text in the terminal. If you do need to, you can prepend additional text ending with a line feed character '\n', or append text starting with a line feed, as this will preserve the disposition of wrapped text.

💡

Alternatively, you can retrieve the underlying terminal strings from the list and manipulate them before converting the message to string.

Warning message

The WarnMessage class is a specialization of the ANSI message.

The default terminal width used by this class is the value of the 'FORCE_WIDTH' environment variable (if present), or the columns property of the standard error stream (i.e., process.stderr). Therefore, this kind of message should be printed with console.error or equivalent.

Error message

The ErrorMessage class is a specialization of a warning message that actually derives from the standard Error class. It should be printed with console.error or equivalent.

Version message

A version message is a plain string, so it has no wrapping. However, it may be remodeled in future versions of the library to accommodate new features. It should be printed with console.log or equivalent.

Machine-readable messages

Machine-readable messages are meant to be consumed by computers. They are described below.

JSON message

The JsonMessage class represents a message in JSON format. It is intended for consumption by introspection tools and other text-processing applications. It should be printed with console.log or equivalent.

Text message

The TextMessage class represents a list of text lines. It is used by the library in two places:

This message produces a string with lines separated by line feeds, and should be printed with console.log or equivalent.