An open API service indexing awesome lists of open source software.

https://github.com/polytypic/prettier-printer

A pretty printing library
https://github.com/polytypic/prettier-printer

pretty-printer text

Last synced: about 1 year ago
JSON representation

A pretty printing library

Awesome Lists containing this project

README

          

# [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#) [Prettier Printer](#prettier-printer) · [![GitHub stars](https://img.shields.io/github/stars/polytypic/prettier-printer.svg?style=social)](https://github.com/polytypic/prettier-printer) [![npm](https://img.shields.io/npm/dm/prettier-printer.svg)](https://www.npmjs.com/package/prettier-printer)

A pretty printing library for text documents that can be rendered to a desired
maximum width. Basic features:

* Interactive documentation (the [▶ links](https://polytypic.github.io/prettier-printer/index.html))
* Functional API:
* [Referentially transparent functions](https://en.wikipedia.org/wiki/Referential_transparency)
* [Curried functions](http://fr.umio.us/favoring-curry/)
* [Supports tree-shaking](https://webpack.js.org/guides/tree-shaking/)
* [TypeScript typings](./src/prettier-printer.d.ts)
* [Contract checking in non-production builds](./src/prettier-printer.js)
* [MIT license](./LICENSE.md)

As an example, the evaluation output in this live
[CodeSandbox](https://codesandbox.io/s/8zo3ko95p2) example is formatted using
this library.

[![npm version](https://badge.fury.io/js/prettier-printer.svg)](http://badge.fury.io/js/prettier-printer)
[![Bower version](https://badge.fury.io/bo/prettier-printer.svg)](https://badge.fury.io/bo/prettier-printer)
[![Build Status](https://travis-ci.org/polytypic/prettier-printer.svg?branch=master)](https://travis-ci.org/polytypic/prettier-printer)
[![Code Coverage](https://img.shields.io/codecov/c/github/polytypic/prettier-printer/master.svg)](https://codecov.io/github/polytypic/prettier-printer?branch=master)
[![](https://david-dm.org/polytypic/prettier-printer.svg)](https://david-dm.org/polytypic/prettier-printer) [![](https://david-dm.org/polytypic/prettier-printer/dev-status.svg)](https://david-dm.org/polytypic/prettier-printer?type=dev)

## [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#contents) [Contents](#contents)

* [Tutorial](#tutorial)
* [Reference](#reference)
* [Rendering documents](#rendering-documents)
* [`PP.render(maxCols, doc) ~> string`](#PP-render) v1.0.0
* [`PP.renderWith({text: (state, string) => state, line: state => state}, state, maxCols, doc) ~> state`](#PP-renderWith) v1.0.0
* [Document constants](#document-constants)
* [`PP.line ~> doc`](#PP-line) v1.0.0
* [`PP.lineBreak ~> doc`](#PP-lineBreak) v1.0.0
* [`PP.softLine ~> doc`](#PP-softLine) v1.0.0
* [`PP.softBreak ~> doc`](#PP-softBreak) v1.0.0
* [Concatenating documents](#concatenating-documents)
* [`PP.append(rhsDoc, lhsDoc) ~> doc`](#PP-append) v1.0.0
* [`PP.prepend(lhsDoc, rhsDoc) ~> doc`](#PP-prepend) v1.0.0
* [Lists of documents](#lists-of-documents)
* [`PP.intersperse(doc, [...docs]) ~> [...docs]`](#PP-intersperse) v1.0.0
* [`PP.punctuate(sepDoc, [...docs]) ~> [...docs]`](#PP-punctuate) v1.0.0
* [Lazy documents](#lazy-documents)
* [`PP.lazy(() => doc) ~> doc`](#PP-lazy) v1.0.0
* [Enclosing documents](#enclosing-documents)
* [`PP.enclose([lhsDoc, rhsDoc], doc) ~> doc`](#PP-enclose) v1.0.0
* [Document pair constants](#document-pair-constants)
* [`PP.angles ~> ['<', '>']`](#PP-angles) v1.0.0
* [`PP.braces ~> ['{', '}']`](#PP-braces) v1.0.0
* PP.brackets ~> ['[', ']'] v1.0.0
* [`PP.dquotes ~> ['"', '"']`](#PP-dquotes) v1.0.0
* [`PP.lineBreaks ~> [PP.lineBreak, PP.lineBreak]`](#PP-lineBreaks) v1.1.0
* [`PP.lines ~> [PP.line, PP.line]`](#PP-lines) v1.1.0
* [`PP.parens ~> ['(', ')']`](#PP-parens) v1.0.0
* [`PP.spaces ~> [' ', ' ']`](#PP-spaces) v1.0.0
* [`PP.squotes ~> ["'", "'"]`](#PP-squotes) v1.0.0
* [Alternative documents](#alternative-documents)
* [`PP.choice(wideDoc, narrowDoc) ~> doc`](#PP-choice) v1.0.0
* [`PP.group(doc) ~> doc`](#PP-group) v1.0.0
* [Nested documents](#nested-documents)
* [`PP.nest(string | number, doc) ~> doc`](#PP-nest) v1.0.0
* [Layout dependent documents](#layout-dependent-documents)
* [`PP.column(column => doc) ~> doc`](#PP-column) v1.0.0
* [`PP.nesting(nesting => doc) ~> doc`](#PP-nesting) v1.0.0
* [Aligned documents](#aligned-documents)
* [`PP.align(doc) ~> doc`](#PP-align) v1.0.0
* [`PP.hang(string | number, doc) ~> doc`](#PP-hang) v1.0.0
* [`PP.indent(string | number, doc) ~> doc`](#PP-indent) v1.0.0
* [Related Work](#related-work)

## [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#tutorial) [Tutorial](#tutorial)

To be done.

In the meanwhile, read Philip Wadler's paper [A prettier
printer](https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf).

## [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#reference) [Reference](#reference)

Typically one imports the library as:

```jsx
import * as PP from 'prettier-printer'
```

The examples also utilize [Ramda](http://ramdajs.com/), bound as `R`.

### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#rendering-documents) [Rendering documents](#rendering-documents)

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-render) [`PP.render(maxCols, doc) ~> string`](#PP-render) 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`](#PP-renderWith).

For example:

```js
PP.render(
10,
PP.indent('-- ', PP.group(PP.intersperse(PP.line, ['Hello,', 'world!'])))
)
// -- Hello,
// -- world!
```

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-renderWith) [`PP.renderWith({text: (state, string) => state, line: state => state}, state, maxCols, doc) ~> state`](#PP-renderWith) 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`](#PP-render).

### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#document-constants) [Document constants](#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.

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-line) [`PP.line ~> doc`](#PP-line) v1.0.0

`PP.line` renders as a new line unless undone by [`PP.group`](#PP-group) in
which case `PP.line` renders as a space.

For example:

```js
PP.render(20, ['Hello,', PP.line, 'world!'])
// Hello,
// world!
```

```js
PP.render(20, PP.group(['Hello,', PP.line, 'world!']))
// Hello, world!
```

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-lineBreak) [`PP.lineBreak ~> doc`](#PP-lineBreak) v1.0.0

`PP.lineBreak` renders as a new line unless undone by [`PP.group`](#PP-group) in
which case `PP.lineBreak` renders as empty.

For example:

```js
PP.render(20, ['Lol', PP.lineBreak, 'Bal'])
// Lol
// Bal
```

```js
PP.render(20, PP.group(['Lol', PP.lineBreak, 'Bal']))
// LolBal
```

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-softLine) [`PP.softLine ~> doc`](#PP-softLine) v1.0.0

`PP.softLine` renders as a space if the output fits and otherwise as a new line.

For example:

```js
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.
```

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-softBreak) [`PP.softBreak ~> doc`](#PP-softBreak) v1.0.0

`PP.softBreak` renders as empty if the output fits and otherwise as a new line.

For example:

```js
PP.render(10, PP.intersperse(PP.softBreak, R.split(/\b/, 'this.method(rocks)')))
// this.
// method(
// rocks)
```

### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#concatenating-documents) [Concatenating documents](#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'`.

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-append) [`PP.append(rhsDoc, lhsDoc) ~> doc`](#PP-append) v1.0.0

`PP.append` reverse concatenates the documents.

For example:

```js
PP.render(0, PP.append('bar', 'foo'))
// foobar
```

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-prepend) [`PP.prepend(lhsDoc, rhsDoc) ~> doc`](#PP-prepend) v1.0.0

`PP.prepend` concatenates the documents.

For example:

```js
PP.render(0, PP.prepend('foo', 'bar'))
// foobar
```

### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#lists-of-documents) [Lists of documents](#lists-of-documents)

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-intersperse) [`PP.intersperse(doc, [...docs]) ~> [...docs]`](#PP-intersperse) v1.0.0

`PP.intersperse` puts the given separator document between each document in the
given list of documents.

For example:

```js
PP.intersperse(',', ['a', 'b', 'c'])
// ['a', ',', 'b', ',', 'c']
```

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-punctuate) [`PP.punctuate(sepDoc, [...docs]) ~> [...docs]`](#PP-punctuate) v1.0.0

`PP.punctuate` concatenates the given separator after each document in the given
list of documents except the last.

For example:

```js
PP.punctuate(',', ['a', 'b', 'c'])
// [ [ 'a', ',' ], [ 'b', ',' ], 'c' ]
```

### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#lazy-documents) [Lazy documents](#lazy-documents)

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-lazy) [`PP.lazy(() => doc) ~> doc`](#PP-lazy) v1.0.0

`PP.lazy` creates a lazy document. The given thunk is only invoked as needed to
compute the document.

### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#enclosing-documents) [Enclosing documents](#enclosing-documents)

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-enclose) [`PP.enclose([lhsDoc, rhsDoc], doc) ~> doc`](#PP-enclose) v1.0.0

`PP.enclose` encloses the given document between the given pair of documents.

For example:

```js
PP.render(0, PP.enclose(PP.parens, 'foo'))
// (foo)
```

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#document-pair-constants) [Document pair constants](#document-pair-constants)

##### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-angles) [`PP.angles ~> ['<', '>']`](#PP-angles) v1.0.0

##### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-braces) [`PP.braces ~> ['{', '}']`](#PP-braces) v1.0.0

##### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-brackets) PP.brackets ~> ['[', ']'] v1.0.0

##### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-dquotes) [`PP.dquotes ~> ['"', '"']`](#PP-dquotes) v1.0.0

##### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-lineBreaks) [`PP.lineBreaks ~> [PP.lineBreak, PP.lineBreak]`](#PP-lineBreaks) v1.1.0

##### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-lines) [`PP.lines ~> [PP.line, PP.line]`](#PP-lines) v1.1.0

##### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-parens) [`PP.parens ~> ['(', ')']`](#PP-parens) v1.0.0

##### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-spaces) [`PP.spaces ~> [' ', ' ']`](#PP-spaces) v1.0.0

##### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-squotes) [`PP.squotes ~> ["'", "'"]`](#PP-squotes) v1.0.0

### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#alternative-documents) [Alternative documents](#alternative-documents)

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-choice) [`PP.choice(wideDoc, narrowDoc) ~> doc`](#PP-choice) 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`](#PP-line)s and [`PP.lineBreak`](#PP-lineBreak)s within the `wideDoc`
are undone like with [`PP.group`](#PP-group).

For example:

```js
PP.render(5, PP.choice('wide', 'narrow'))
// 'wide'
```

```js
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:

```js
const hyphen = PP.choice('', ['-', PP.lineBreak])

PP.render(5, PP.intersperse(hyphen, ['hy', 'phen', 'at', 'ed']))
// hy-
// phen-
// ated
```

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-group) [`PP.group(doc) ~> doc`](#PP-group) v1.0.0

`PP.group` allows [`PP.line`](#PP-line)s and [`PP.lineBreak`](#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)`](#PP-choice).

### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#nested-documents) [Nested documents](#nested-documents)

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-nest) [`PP.nest(string | number, doc) ~> doc`](#PP-nest) 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:

```js
PP.render(6, PP.nest(2, PP.group(PP.intersperse(PP.line, ['foo', 'bar']))))
// foo
// bar
```

### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#layout-dependent-documents) [Layout dependent documents](#layout-dependent-documents)

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-column) [`PP.column(column => doc) ~> doc`](#PP-column) v1.0.0

`PP.column` allows a document to depend on the column at which the document
starts.

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-nesting) [`PP.nesting(nesting => doc) ~> doc`](#PP-nesting) v1.0.0

`PP.nesting` allows a document to depend on the nesting after the next new line.

### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#aligned-documents) [Aligned documents](#aligned-documents)

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-align) [`PP.align(doc) ~> doc`](#PP-align) v1.0.0

`PP.align` creates a document such that the nesting of the document is aligned
to the current column.

For example:

```js
PP.render(10, PP.group(['foo(', PP.align(['bar,', PP.line, 'baz']), ')']))
// foo(bar,
// baz)
```

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-hang) [`PP.hang(string | number, doc) ~> doc`](#PP-hang) 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:

```js
PP.render(10, PP.group(['foo(', PP.hang(2, ['bar,', PP.line, 'baz']), ')']))
// foo(bar,
// baz)
```

#### [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#PP-indent) [`PP.indent(string | number, doc) ~> doc`](#PP-indent) 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.

```js
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.
```

## [≡](#contents) [▶](https://polytypic.github.io/prettier-printer/index.html#related-work) [Related Work](#related-work)

* Philip Wadler's paper [A prettier
printer](https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf)
describes the basic ideas and implementation.
* [Text.PrettyPrint.Leijen](https://hackage.haskell.org/package/wl-pprint-1.2/docs/Text-PrettyPrint-Leijen.html)
is Daan Leijen's implementation with some extensions.
* Other prettier printer implementations by the author of this library:
* [prettier](https://github.com/MLton/mltonlib/tree/master/com/ssh/prettier/unstable)
* [PPrint](https://github.com/polytypic/PPrint)
* [text.pretty-printing](https://github.com/folktale/text.pretty-printing)
another JS implementation based on Wadler's paper. Marked as
"[Unmaintained]".
* [Prettier](https://prettier.io/) uses a similar pretty printing library
underneath.