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 intensityfaint
- faint, decreased intensity, or dimitalic
- italicunderlined
- underlinedslowlyBlinking
- slowly blinkingrapidlyBlinking
- rapidly blinkinginverse
- reverse video or inverse (flips foreground and background color)invisible
- invisible, concealed or hiddencrossedOut
- crossed-out or strikethroughdoublyUnderlined
- doubly underlinedproportionalSpacing
- proportional spacing
Font-changing attributes
primaryFont
- primary fontalternative[1-9]
- alternative font 1 through 9fraktur
- black-letter font
Ideogram attributes
ideogramUnderline
- ideogram underline or right side lineideogramDoubleUnderline
- ideogram double underline, or double line on the right sideideogramOverline
- ideogram overline or left side lineideogramDoubleOverline
- ideogram double overline, or double line on the left sideideogramStressMarking
- ideogram stress marking
Miscellaneous attributes
framed
- framedencircled
- encircledoverlined
- overlinedsuperscript
- superscriptsubscript
- subscript
Resetting attributes
clear
- resets any other preceding SGR attributenotBoldOrFaint
- normal intensity (neither bold nor faint)notItalicNorFraktur
- regular face (neither italic nor black-letter)notUnderlined
- not underlinednotBlinking
- steady (not blinking)notInverse
- positive (not inverse)notInvisible
- visible (reveal, or not hidden)notCrossedOut
- not crossed out (no strikethrough)notProportionalSpacing
- disable proportional spacingnotFramedOrEncircled
- neither framed nor encirclednotOverlined
- not overlinednoIdeogram
- no ideogram attributesnotSuperscriptOrSubscript
- 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
- blackred
- redgreen
- greenyellow
- yellowblue
- bluemagenta
- magentacyan
- cyanwhite
- white
High-intensity colors
brightBlack
- bright black (gray)brightRed
- bright redbrightGreen
- bright greenbrightYellow
- bright yellowbrightBlue
- bright bluebrightMagenta
- bright magentabrightCyan
- bright cyanbrightWhite
- 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 valuebg8
- creates a background color from an 8-bit decimal valueul8
- creates an underline color from an 8-bit decimal value
Underline styles
The ul
constant holds the styles of underlined text:
none
- no underlinesingle
- single underlinedouble
- double underlinecurly
- curly underlinedotted
- dotted underlinedashed
- 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:
- by both the parser and validator, to create error and warning messages
- by the formatter, to build help messages
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:
- by the both the parser and validator, to produce error and warning messages based on configured error phrases
- by the formatter, to assemble help items from configured help phrases
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 values
- a string valuen
- a number valuer
- a regular expressiono
- an option namev
- an unknown value (enclosed in angle brackets, like the parameter column)u
- a URL hyperlinkt
- a general textp
- 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 widthNO_COLOR
- force omission of styles regardless of the terminal widthTERM
- set to'dumb'
to achieve the same behavior asNO_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:
- by the parser to throw completion words, in which case it is meant to be consumed by the completion builtins
- by the formatter to create help messages in either CSV or Markdown format
This message produces a string with lines separated by line feeds, and should be printed with
console.log
or equivalent.