prettier-printer
v1.1.4
Published
A pretty printing library
Downloads
1,505
Readme
≡ ▶ Prettier Printer ·
A pretty printing library for text documents that can be rendered to a desired maximum width. Basic features:
- Interactive documentation (the ▶ links)
- Functional API:
- Supports tree-shaking
- TypeScript typings
- Contract checking in non-production builds
- MIT license
As an example, the evaluation output in this live CodeSandbox example is formatted using this library.
≡ ▶ Contents
- Tutorial
- Reference
- Rendering documents
- Document constants
PP.line ~> doc
v1.0.0PP.lineBreak ~> doc
v1.0.0PP.softLine ~> doc
v1.0.0PP.softBreak ~> doc
v1.0.0
- Concatenating documents
- Lists of documents
- Lazy documents
PP.lazy(() => doc) ~> doc
v1.0.0
- Enclosing documents
PP.enclose([lhsDoc, rhsDoc], doc) ~> doc
v1.0.0- Document pair constants
PP.angles ~> ['<', '>']
v1.0.0PP.braces ~> ['{', '}']
v1.0.0- PP.brackets ~> ['[', ']'] v1.0.0
PP.dquotes ~> ['"', '"']
v1.0.0PP.lineBreaks ~> [PP.lineBreak, PP.lineBreak]
v1.1.0PP.lines ~> [PP.line, PP.line]
v1.1.0PP.parens ~> ['(', ')']
v1.0.0PP.spaces ~> [' ', ' ']
v1.0.0PP.squotes ~> ["'", "'"]
v1.0.0
- Alternative documents
PP.choice(wideDoc, narrowDoc) ~> doc
v1.0.0PP.group(doc) ~> doc
v1.0.0
- Nested documents
- Layout dependent documents
- Aligned documents
- Related Work
≡ ▶ Tutorial
To be done.
In the meanwhile, read Philip Wadler's paper A prettier printer.
≡ ▶ Reference
Typically one imports the library as:
import * as PP from 'prettier-printer'
The examples also utilize Ramda, bound as R
.
≡ ▶ Rendering documents
≡ ▶ PP.render(maxCols, doc) ~> string
v1.0.0
PP.render
renders the document to a string trying to keep the width of the
document within the specified maximum. A width of 0
means that there is no
maximum. See also PP.renderWith
.
For example:
PP.render(
10,
PP.indent('-- ', PP.group(PP.intersperse(PP.line, ['Hello,', 'world!'])))
)
// -- Hello,
// -- world!
≡ ▶ PP.renderWith({text: (state, string) => state, line: state => state}, state, maxCols, doc) ~> state
v1.0.0
PP.renderWith
renders the document with the given actions text
and line
.
You can use this function to output the document without creating an
intermediate string of the whole document. See also PP.render
.
≡ ▶ Document constants
Any string that doesn't contain '\n'
or '\r'
characters is considered as an
atomic document. For example, ''
is an empty document and ' '
is a space.
≡ ▶ PP.line ~> doc
v1.0.0
PP.line
renders as a new line unless undone by PP.group
in
which case PP.line
renders as a space.
For example:
PP.render(20, ['Hello,', PP.line, 'world!'])
// Hello,
// world!
PP.render(20, PP.group(['Hello,', PP.line, 'world!']))
// Hello, world!
≡ ▶ PP.lineBreak ~> doc
v1.0.0
PP.lineBreak
renders as a new line unless undone by PP.group
in
which case PP.lineBreak
renders as empty.
For example:
PP.render(20, ['Lol', PP.lineBreak, 'Bal'])
// Lol
// Bal
PP.render(20, PP.group(['Lol', PP.lineBreak, 'Bal']))
// LolBal
≡ ▶ PP.softLine ~> doc
v1.0.0
PP.softLine
renders as a space if the output fits and otherwise as a new line.
For example:
PP.render(
20,
PP.intersperse(
PP.softLine,
R.split(
/\s+/,
'Here is a paragraph of text that we will format to a desired width.'
)
)
)
// Here is a paragraph
// of text that we will
// format to a desired
// width.
≡ ▶ PP.softBreak ~> doc
v1.0.0
PP.softBreak
renders as empty if the output fits and otherwise as a new line.
For example:
PP.render(10, PP.intersperse(PP.softBreak, R.split(/\b/, 'this.method(rocks)')))
// this.
// method(
// rocks)
≡ ▶ Concatenating documents
An array of documents is considered as a concatenation of documents. For
example, []
is an empty document and ['foo', 'bar']
is equivalent to
'foobar'
.
≡ ▶ PP.append(rhsDoc, lhsDoc) ~> doc
v1.0.0
PP.append
reverse concatenates the documents.
For example:
PP.render(0, PP.append('bar', 'foo'))
// foobar
≡ ▶ PP.prepend(lhsDoc, rhsDoc) ~> doc
v1.0.0
PP.prepend
concatenates the documents.
For example:
PP.render(0, PP.prepend('foo', 'bar'))
// foobar
≡ ▶ Lists of documents
≡ ▶ PP.intersperse(doc, [...docs]) ~> [...docs]
v1.0.0
PP.intersperse
puts the given separator document between each document in the
given list of documents.
For example:
PP.intersperse(',', ['a', 'b', 'c'])
// ['a', ',', 'b', ',', 'c']
≡ ▶ PP.punctuate(sepDoc, [...docs]) ~> [...docs]
v1.0.0
PP.punctuate
concatenates the given separator after each document in the given
list of documents except the last.
For example:
PP.punctuate(',', ['a', 'b', 'c'])
// [ [ 'a', ',' ], [ 'b', ',' ], 'c' ]
≡ ▶ Lazy documents
≡ ▶ PP.lazy(() => doc) ~> doc
v1.0.0
PP.lazy
creates a lazy document. The given thunk is only invoked as needed to
compute the document.
≡ ▶ Enclosing documents
≡ ▶ PP.enclose([lhsDoc, rhsDoc], doc) ~> doc
v1.0.0
PP.enclose
encloses the given document between the given pair of documents.
For example:
PP.render(0, PP.enclose(PP.parens, 'foo'))
// (foo)
≡ ▶ Document pair constants
≡ ▶ PP.angles ~> ['<', '>']
v1.0.0
≡ ▶ PP.braces ~> ['{', '}']
v1.0.0
≡ ▶ PP.brackets ~> ['[', ']'] v1.0.0
≡ ▶ PP.dquotes ~> ['"', '"']
v1.0.0
≡ ▶ PP.lineBreaks ~> [PP.lineBreak, PP.lineBreak]
v1.1.0
≡ ▶ PP.lines ~> [PP.line, PP.line]
v1.1.0
≡ ▶ PP.parens ~> ['(', ')']
v1.0.0
≡ ▶ PP.spaces ~> [' ', ' ']
v1.0.0
≡ ▶ PP.squotes ~> ["'", "'"]
v1.0.0
≡ ▶ Alternative documents
≡ ▶ PP.choice(wideDoc, narrowDoc) ~> doc
v1.0.0
PP.choice(wideDoc, narrowDoc)
renders as the given wideDoc
on a line if it
fits within the maximum width and otherwise as the narrowDoc
.
PP.line
s and PP.lineBreak
s within the wideDoc
are undone like with PP.group
.
For example:
PP.render(5, PP.choice('wide', 'narrow'))
// 'wide'
PP.render(3, PP.choice('wide', 'narrow'))
// 'narrow'
Note that usually the idea is that the narrow version can indeed be rendered more narrowly.
For example:
const hyphen = PP.choice('', ['-', PP.lineBreak])
PP.render(5, PP.intersperse(hyphen, ['hy', 'phen', 'at', 'ed']))
// hy-
// phen-
// ated
≡ ▶ PP.group(doc) ~> doc
v1.0.0
PP.group
allows PP.line
s and PP.lineBreak
s
within the given document to be undone if the result fits within the maximum
width. PP.group(doc)
is equivalent to PP.choice(doc, doc)
.
≡ ▶ Nested documents
≡ ▶ PP.nest(string | number, doc) ~> doc
v1.0.0
PP.nest
increases the nesting after next new line by the given string or by
the given number of spaces.
For example:
PP.render(6, PP.nest(2, PP.group(PP.intersperse(PP.line, ['foo', 'bar']))))
// foo
// bar
≡ ▶ Layout dependent documents
≡ ▶ PP.column(column => doc) ~> doc
v1.0.0
PP.column
allows a document to depend on the column at which the document
starts.
≡ ▶ PP.nesting(nesting => doc) ~> doc
v1.0.0
PP.nesting
allows a document to depend on the nesting after the next new line.
≡ ▶ Aligned documents
≡ ▶ PP.align(doc) ~> doc
v1.0.0
PP.align
creates a document such that the nesting of the document is aligned
to the current column.
For example:
PP.render(10, PP.group(['foo(', PP.align(['bar,', PP.line, 'baz']), ')']))
// foo(bar,
// baz)
≡ ▶ PP.hang(string | number, doc) ~> doc
v1.0.0
PP.hang
creates a document such that the document is nested by the given
string or number of spaces starting from the current column.
For example:
PP.render(10, PP.group(['foo(', PP.hang(2, ['bar,', PP.line, 'baz']), ')']))
// foo(bar,
// baz)
≡ ▶ PP.indent(string | number, doc) ~> doc
v1.0.0
PP.indent
creates a document such that the document is indented by the given
prefix or number of spaces starting from the current column.
PP.render(
20,
PP.nest(
2,
PP.group([
'A comment:',
PP.line,
PP.line,
PP.indent(
'-- ',
PP.intersperse(
PP.softLine,
R.split(/\s+/, 'This is the comment that you are looking for.')
)
)
])
)
)
// A comment:
//
// -- This is the
// -- comment that
// -- you are looking
// -- for.
≡ ▶ Related Work
- Philip Wadler's paper A prettier printer describes the basic ideas and implementation.
- Text.PrettyPrint.Leijen is Daan Leijen's implementation with some extensions.
- Other prettier printer implementations by the author of this library:
- text.pretty-printing another JS implementation based on Wadler's paper. Marked as "[Unmaintained]".
- Prettier uses a similar pretty printing library underneath.