or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

comments.mdconfiguration.mdcore-printing.mddocument-system.mdextras.mdindex.mdregistration.md

document-system.mddocs/

0

# Document System

1

2

Low-level document creation and manipulation functions for building custom layout algorithms and pretty printers. The document system provides the foundation for prettyprinter's flexible and composable formatting capabilities.

3

4

## Capabilities

5

6

### Document Creation

7

8

Core functions for creating and combining document elements that represent formatted output structure.

9

10

```python { .api }

11

def concat(docs):

12

"""

13

Create document by concatenating a sequence of documents.

14

15

Parameters:

16

- docs: Iterable of documents (Doc instances or strings)

17

18

Returns:

19

- Doc: Concatenated document

20

21

Notes:

22

- Empty documents (NIL) are automatically filtered out

23

- String arguments are automatically converted to document format

24

"""

25

26

def group(doc):

27

"""

28

Create document that attempts single-line layout when possible.

29

30

Parameters:

31

- doc: Document to attempt to lay out on single line

32

33

Returns:

34

- Doc: Grouped document that tries flat layout first

35

36

Notes:

37

- Uses 'when_flat' branch of FlatChoice documents when fitting on one line

38

- Falls back to multiline layout when content doesn't fit

39

"""

40

41

def nest(i, doc):

42

"""

43

Create document with increased indentation level.

44

45

Parameters:

46

- i (int): Number of spaces to add to indentation

47

- doc: Document to indent

48

49

Returns:

50

- Doc: Document with increased indentation

51

"""

52

```

53

54

### Document Annotation

55

56

Functions for adding metadata and annotations to documents for syntax highlighting and other purposes.

57

58

```python { .api }

59

def annotate(annotation, doc):

60

"""

61

Annotate document with arbitrary metadata value.

62

63

Parameters:

64

- annotation: Arbitrary annotation value (often Token for syntax highlighting)

65

- doc: Document to annotate

66

67

Returns:

68

- Doc: Annotated document with metadata

69

70

Notes:

71

- Annotations are preserved through layout process

72

- Used extensively for syntax highlighting with Token values

73

"""

74

```

75

76

### Contextual Documents

77

78

Create documents that are evaluated lazily based on layout context, enabling adaptive formatting based on available space and current formatting state.

79

80

```python { .api }

81

def contextual(fn):

82

"""

83

Create document that is lazily evaluated during layout.

84

85

Parameters:

86

- fn: Function accepting (indent, column, page_width, ribbon_width) parameters

87

88

Returns:

89

- Doc: Contextual document evaluated during layout

90

91

Notes:

92

- Enables adaptive formatting based on current layout state

93

- Function is called during layout with current position and constraints

94

- Returned value from function must be a valid document

95

"""

96

```

97

98

### Advanced Layout Control

99

100

Functions providing fine-grained control over document layout behavior and line breaking.

101

102

```python { .api }

103

def always_break(doc):

104

"""

105

Create document that forces multiline layout.

106

107

Parameters:

108

- doc: Document to force to multiple lines

109

110

Returns:

111

- Doc: Document that will always break to multiple lines

112

113

Notes:

114

- Forces parent documents to also break to multiple lines

115

- Nested documents may still be laid out flat independently

116

"""

117

118

def flat_choice(when_broken, when_flat):

119

"""

120

Create document with conditional layout options.

121

122

Parameters:

123

- when_broken: Document used when parent is broken to multiple lines

124

- when_flat: Document used when parent fits on single line

125

126

Returns:

127

- Doc: Document with conditional layout behavior

128

129

Notes:

130

- Layout algorithm chooses appropriate branch based on fitting constraints

131

- Used internally by LINE, SOFTLINE constants

132

"""

133

134

def align(doc):

135

"""

136

Align each new line in document with the first new line.

137

138

Parameters:

139

- doc: Document to align

140

141

Returns:

142

- Doc: Document with aligned continuation lines

143

"""

144

145

def hang(i, doc):

146

"""

147

Create hanging indent document.

148

149

Parameters:

150

- i (int): Hanging indentation amount

151

- doc: Document to apply hanging indent to

152

153

Returns:

154

- Doc: Document with hanging indentation

155

"""

156

157

def fill(docs):

158

"""

159

Create document that fills lines optimally with content.

160

161

Parameters:

162

- docs: Iterable of documents to fill

163

164

Returns:

165

- Doc: Document with optimal line filling

166

167

Notes:

168

- Attempts to fit as much content as possible on each line

169

- Breaks to new lines when content doesn't fit

170

"""

171

```

172

173

### Document Constants

174

175

Pre-defined document constants for common layout elements.

176

177

```python { .api }

178

# Document constants

179

NIL # Empty document (no output)

180

LINE # Line break or space (context-dependent)

181

SOFTLINE # Line break or nothing (context-dependent)

182

HARDLINE # Forced line break

183

```

184

185

## Usage Examples

186

187

### Basic Document Construction

188

189

```python

190

from prettyprinter.doc import concat, group, nest, always_break

191

from prettyprinter.doc import NIL, LINE, SOFTLINE, HARDLINE

192

193

# Simple concatenation

194

doc = concat(['Hello', ' ', 'World'])

195

196

# Grouped content that tries to fit on one line

197

grouped = group(concat(['[', '1', ',', LINE, '2', ',', LINE, '3', ']']))

198

199

# Nested indentation

200

indented = nest(4, concat(['def foo():', HARDLINE, 'return 42']))

201

```

202

203

### Custom Pretty Printer with Documents

204

205

```python

206

from prettyprinter import register_pretty

207

from prettyprinter.doc import concat, group, nest, annotate

208

from prettyprinter.doc import LINE, HARDLINE

209

from prettyprinter.syntax import Token

210

211

class Matrix:

212

def __init__(self, rows):

213

self.rows = rows

214

215

@register_pretty(Matrix)

216

def pretty_matrix(matrix, ctx):

217

# Create rows as documents

218

row_docs = []

219

for row in matrix.rows:

220

row_doc = concat([

221

'[',

222

concat([

223

str(item) if i == 0 else concat([',', LINE, str(item)])

224

for i, item in enumerate(row)

225

]),

226

']'

227

])

228

row_docs.append(row_doc)

229

230

# Combine rows with proper indentation

231

return group(concat([

232

annotate(Token.NAME_FUNCTION, 'Matrix'),

233

'(',

234

nest(ctx.indent, concat([

235

HARDLINE,

236

concat([

237

row_doc if i == 0 else concat([',', HARDLINE, row_doc])

238

for i, row_doc in enumerate(row_docs)

239

])

240

])),

241

HARDLINE,

242

')'

243

]))

244

245

# Usage

246

matrix = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

247

pprint(matrix)

248

```

249

250

### Contextual Document Example

251

252

```python

253

from prettyprinter.doc import contextual, concat

254

from prettyprinter import register_pretty

255

256

class AdaptiveList:

257

def __init__(self, items):

258

self.items = items

259

260

@register_pretty(AdaptiveList)

261

def pretty_adaptive_list(alist, ctx):

262

def make_adaptive_doc(indent, column, page_width, ribbon_width):

263

available_width = page_width - column

264

265

if available_width > 50:

266

# Wide format: all on one line

267

return concat([

268

'AdaptiveList([',

269

', '.join(str(item) for item in alist.items),

270

'])'

271

])

272

else:

273

# Narrow format: vertical layout

274

item_docs = [concat([str(item), ',' if i < len(alist.items)-1 else ''])

275

for i, item in enumerate(alist.items)]

276

return concat([

277

'AdaptiveList([',

278

nest(4, concat([HARDLINE, *[concat([item_doc, HARDLINE])

279

for item_doc in item_docs]])),

280

'])'

281

])

282

283

return contextual(make_adaptive_doc)

284

```

285

286

### Advanced Layout with Flat Choice

287

288

```python

289

from prettyprinter.doc import flat_choice, concat, always_break

290

from prettyprinter import register_pretty

291

292

class FlexibleDict:

293

def __init__(self, data):

294

self.data = data

295

296

@register_pretty(FlexibleDict)

297

def pretty_flexible_dict(fdict, ctx):

298

if not fdict.data:

299

return 'FlexibleDict({})'

300

301

# Create key-value pair documents

302

pairs = []

303

for key, value in fdict.data.items():

304

pair = flat_choice(

305

when_broken=concat([

306

repr(key), ':', HARDLINE,

307

nest(4, str(value))

308

]),

309

when_flat=concat([repr(key), ': ', str(value)])

310

)

311

pairs.append(pair)

312

313

# Combine pairs

314

combined = concat([

315

pairs[0] if i == 0 else concat([',', LINE, pair])

316

for i, pair in enumerate(pairs)

317

])

318

319

return group(concat([

320

'FlexibleDict({',

321

nest(4, concat([SOFTLINE, combined])),

322

SOFTLINE,

323

'})'

324

]))

325

```

326

327

### Document Validation and Debugging

328

329

```python

330

from prettyprinter.doc import concat

331

from prettyprinter.doctypes import Doc

332

333

def debug_document_structure(doc, level=0):

334

"""Print document structure for debugging."""

335

indent = ' ' * level

336

337

if isinstance(doc, str):

338

print(f"{indent}String: {repr(doc)}")

339

elif isinstance(doc, Doc):

340

print(f"{indent}{type(doc).__name__}")

341

if hasattr(doc, 'docs'): # Concat, Fill

342

for subdoc in doc.docs:

343

debug_document_structure(subdoc, level + 1)

344

elif hasattr(doc, 'doc'): # Group, Nest, AlwaysBreak, Annotated

345

debug_document_structure(doc.doc, level + 1)

346

elif hasattr(doc, 'when_flat'): # FlatChoice

347

print(f"{indent} when_flat:")

348

debug_document_structure(doc.when_flat, level + 2)

349

print(f"{indent} when_broken:")

350

debug_document_structure(doc.when_broken, level + 2)

351

352

# Example usage

353

doc = group(concat(['hello', LINE, 'world']))

354

debug_document_structure(doc)

355

```

356

357

### Custom Document Types

358

359

```python

360

from prettyprinter.doctypes import Doc

361

from prettyprinter.doc import concat

362

363

class Highlight(Doc):

364

"""Custom document type for highlighting."""

365

366

def __init__(self, doc, color='red'):

367

self.doc = doc

368

self.color = color

369

370

def normalize(self):

371

from prettyprinter.doc import validate_doc # Internal function

372

return Highlight(validate_doc(self.doc), self.color)

373

374

def __repr__(self):

375

return f'Highlight({self.doc!r}, {self.color!r})'

376

377

# Example class

378

class ImportantData:

379

def __init__(self, value):

380

self.value = value

381

382

# Use in pretty printer

383

@register_pretty(ImportantData)

384

def pretty_important_data(data, ctx):

385

return concat([

386

'ImportantData(',

387

Highlight(str(data.value), 'yellow'),

388

')'

389

])

390

```