@elastic/pretty-printer

中文文档
4.39.0发布于 2026/11/11Elastic-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 54.9万

A general-purpose Wadler-Lindig document algebra and layout engine for width-aware pretty-printing.

原始使用文档
文档目录12 节
  1. Install
  2. How it works
  3. layout(tree, opts?)
  4. Combinators / Commands
  5. Primitives
  6. Line breaks
  7. Grouping
  8. Indentation
  9. Conditional content
  10. Comments & line suffixes
  11. Miscellaneous
  12. Traversal

@elastic/pretty-printer

A general-purpose pretty-printing library based on the Wadler-Lindig document algebra (Philip Wadler, "A prettier printer", 2003; Christian Lindig's strict formulation). The implementation draws heavily from Prettier's internal doc-printer.

It contains no ES|QL, PromQL, or other domain knowledge — it is the standalone layout engine used by @elastic/esql's pretty-printers, published so any project can build width-aware formatters on the same Doc IR.

Install

npm install @elastic/pretty-printer

How it works

Pretty-printing is a two-phase process:

  1. Build a document tree (Doc) using combinators (see below). The tree describes the structure of possible layouts — it contains no concrete line breaks or indentation yet.
  2. Layout the tree into a concrete string. The layout engine fits as much content on each line as possible (up to printWidth), breaking group nodes when the flat representation would exceed the available width.

Example:

import { text, group, indent, line, softline, join, layout } from '@elastic/pretty-printer';

const doc = group([
  text('SELECT'),
  indent([line, join(
    [text(','), line],
    [text('a'), text('b'), text('c')])]
  ),
  line,
  text('FROM t'),
]);

layout(doc, { printWidth: 40 });
// SELECT
//   a,
//   b,
//   c
// FROM t

layout(doc, { printWidth: 80 });
// SELECT a, b, c FROM t

layout(tree, opts?)

The main entry point. Takes a print tree and returns the formatted string.

Options:

OptionTypeDefaultDescription
printWidthnumber80Target maximum line width.
tabWidthnumber2Spaces per indentation level.
useTabsbooleanfalseIndent with tabs instead of spaces.
endOfLine'\n' | '\r\n' | '\r''\n'Line-ending character(s).

Combinators / Commands

The printer provides a set of combinators (or "commands") for building print trees. These are the building blocks for describing the structure of the output.

Primitives

  • text(string) — Literal text, printed as-is. Must not contain newline characters.
  • Doc[] (array) — Concatenation. An array of docs is rendered left to right.

Line breaks

  • line — Space " " in flat mode; newline + indent in break mode.
  • softline — Nothing "" in flat mode; newline + indent in break mode.
  • hardline — Always a newline + indent. Forces the enclosing group to break.
  • hardlineWithoutBreakParent — Like hardline but does not force the parent group to break.
  • literalline — Hard line break that indents to the root position (set by markAsRoot) instead of the current nesting level. Preserves trailing whitespace. Forces enclosing groups to break.
  • literallineWithoutBreakParent — Like literalline but does not force the parent group to break.

Grouping

  • group(tree, opts?) — The core break-decision unit. Tries to render print tree node flat (single line). If it exceeds the remaining width, switches to break mode. Options: shouldBreak (force break), id (symbol for cross-referencing with ifBreak/indentIfBreak).
  • conditionalGroup(states, opts?) — Multi-state group. Provide alternative layouts from most compact to most expanded. The engine tries each in order and uses the first one that fits; if none fits, the last state is rendered in break mode.
  • fill(parts) — Wrapping layout. parts alternate between content and line-break docs: [item, line, item, line, ...]. Fills each line with as many items as fit before breaking — unlike group, which is all-or-nothing.

Indentation

  • indent(tree) — Increase indentation by one tab level.
  • align(n, tree) — Increase indentation by exactly n spaces (not a tab level). Special values: -1 (dedent one level), Number.NEGATIVE_INFINITY (reset to root), { type: 'root' } (mark current indent as root).
  • dedent(tree) — Decrease indentation by one level. Shorthand for align(-1, tree).
  • dedentToRoot(tree) — Reset indentation to root (column 0 or the position set by markAsRoot).
  • markAsRoot(tree) — Mark the current indentation as the "root" position for literalline.

Conditional content

  • ifBreak(breakDoc, flatDoc?, opts?) — Emit breakDoc when the enclosing group (or a group referenced by groupId) is in break mode; otherwise emit flatDoc.
  • indentIfBreak(tree, opts) — Conditionally indent doc based on a referenced group's mode. Optimized form of ifBreak(indent(tree), doc, { groupId }). Set negate: true to reverse.
  • breakParent — Force all ancestor groups to break. Propagated during a pre-pass (propagateBreaks).

Comments & line suffixes

  • lineSuffix(tree) — Buffer doc and emit it at the end of the current line, just before the next line break. Used for trailing comments.
  • lineSuffixBoundary — Force-flush any pending lineSuffix content. Prevents trailing comments from leaking past syntactic boundaries.

Miscellaneous

  • label(lbl, tree) — Annotate a doc with an opaque label for language-specific heuristic introspection. No effect on layout.
  • trim — Remove all trailing whitespace from the output at the current position.
  • cursor — Placeholder for cursor-position tracking. The layout engine emits a sentinel; callers can locate it to preserve cursor position after formatting.
  • join(separator, trees) — Join an array of docs with separator between each pair.
  • bracketedList(open, close, sep, items) — Convenience for a grouped, indented, bracketed list. Flat: (a, b, c). Broken:
    (
      a,
      b,
      c
    )
    
  • addAlignmentToDoc(doc, size, tabWidth) — Convert an absolute indentation size into nested indent/align wrappers inside dedentToRoot. Used for embedded content needing a specific indentation level.

Traversal

  • traverse(doc, { onEnter?, onExit? }) — Generic depth-first traversal of a doc tree using an explicit stack (no recursion). Return false from onEnter to skip a node's children.

版本与发布记录

@elastic/pretty-printer 共发布 38 个版本,首次发布于 2026/07/02;过去 12 个月发布了 38 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
4.39.0latest2026/11/112 天前
4.38.02026/11/094 天前
4.37.02026/11/058 天前
4.36.02026/11/0211 天前
4.35.02026/10/2915 天前
4.34.02026/10/2618 天前

关于 @elastic/pretty-printer 的常见问题

@elastic/pretty-printer 是什么?

A general-purpose Wadler-Lindig document algebra and layout engine for width-aware pretty-printing.

如何安装 @elastic/pretty-printer?

在项目目录运行 npm install @elastic/pretty-printer,或使用 pnpm add / yarn add / bun add。

@elastic/pretty-printer 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@elastic/pretty-printer 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@elastic/pretty-printer 可以商用吗?

@elastic/pretty-printer 使用 Elastic-2.0 许可。声明的许可为 Elastic-2.0,请阅读许可原文确认使用条件。以上为概括,不构成法律意见,请以许可原文为准。

@elastic/pretty-printer 的下载量有多少?

根据 npm 官方下载统计,@elastic/pretty-printer 在 2026/10/14 – 2026/11/12 这 30 天内被下载 549,280 次,日均约 18,309 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@elastic/pretty-printer 还在维护吗?

最新版本 4.39.0 发布于 2026/11/11(2 天前);至今共发布 38 个版本,其中过去 12 个月发布了 38 个;首次发布于 2026/07/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。