or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-blacken-docs

Run Black on Python code blocks in documentation files.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/blacken-docs@1.19.x

To install, run

npx @tessl/cli install tessl/pypi-blacken-docs@1.19.0

0

# blacken-docs

1

2

A command-line tool that runs Black on Python code blocks in documentation files. It automatically formats Python code examples in Markdown, reStructuredText, and LaTeX files, helping maintain consistent code style across technical documentation, tutorials, and API documentation.

3

4

## Package Information

5

6

- **Package Name**: blacken-docs

7

- **Language**: Python

8

- **Installation**: `pip install blacken-docs`

9

- **Python Support**: 3.9 to 3.13

10

- **Black Compatibility**: 22.1.0+

11

12

## Core Imports

13

14

```python

15

import blacken_docs

16

```

17

18

For programmatic use:

19

20

```python

21

from blacken_docs import format_str, format_file, main, CodeBlockError

22

```

23

24

## Basic Usage

25

26

### Command Line Usage

27

28

Process single files:

29

30

```bash

31

blacken-docs README.rst

32

blacken-docs docs/api.md

33

```

34

35

Process multiple files with glob patterns:

36

37

```bash

38

git ls-files -z -- '*.md' | xargs -0 blacken-docs

39

git ls-files -z -- '*.rst' | xargs -0 blacken-docs

40

```

41

42

### Programmatic Usage

43

44

```python

45

import blacken_docs

46

import black

47

48

# Format code blocks in a string

49

content = '''

50

```python

51

def hello( ):

52

print( "hello world" )

53

```

54

'''

55

56

# Both black.Mode and black.FileMode work (they are equivalent)

57

black_mode = black.Mode(line_length=88)

58

formatted_content, errors = blacken_docs.format_str(content, black_mode)

59

60

# Format code blocks in a file

61

exit_code = blacken_docs.format_file(

62

filename="README.md",

63

black_mode=black_mode,

64

skip_errors=False,

65

rst_literal_blocks=False,

66

check_only=False

67

)

68

```

69

70

## Capabilities

71

72

### String Formatting

73

74

Formats Python code blocks within a string using Black formatter.

75

76

```python { .api }

77

def format_str(

78

src: str,

79

black_mode: black.FileMode,

80

*,

81

rst_literal_blocks: bool = False

82

) -> tuple[str, Sequence[CodeBlockError]]:

83

"""

84

Format Python code blocks within documentation text.

85

86

Parameters:

87

- src: str - Input documentation text containing code blocks

88

- black_mode: black.FileMode - Black formatting configuration

89

- rst_literal_blocks: bool - Whether to format reStructuredText literal blocks (default: False)

90

91

Returns:

92

- tuple[str, Sequence[CodeBlockError]] - Formatted text and any parsing errors

93

"""

94

```

95

96

### File Formatting

97

98

Formats Python code blocks in documentation files and writes changes back to disk.

99

100

```python { .api }

101

def format_file(

102

filename: str,

103

black_mode: black.FileMode,

104

skip_errors: bool,

105

rst_literal_blocks: bool,

106

check_only: bool

107

) -> int:

108

"""

109

Format Python code blocks in a documentation file.

110

111

Parameters:

112

- filename: str - Path to documentation file to format

113

- black_mode: black.FileMode - Black formatting configuration

114

- skip_errors: bool - Whether to skip syntax errors and continue processing

115

- rst_literal_blocks: bool - Whether to format reStructuredText literal blocks

116

- check_only: bool - Whether to only check without modifying the file

117

118

Returns:

119

- int - Exit code (0=no changes needed, 1=changes made, 2=errors occurred)

120

"""

121

```

122

123

### Command Line Interface

124

125

Main entry point for command-line usage supporting all Black formatting options plus additional features.

126

127

```python { .api }

128

def main(argv: Sequence[str] | None = None) -> int:

129

"""

130

Main CLI function that processes files with Python code blocks.

131

132

Parameters:

133

- argv: Sequence[str] | None - Command line arguments (uses sys.argv if None)

134

135

Returns:

136

- int - Exit code for the operation

137

"""

138

```

139

140

### Error Handling

141

142

Error class for capturing code block parsing failures with location information.

143

144

```python { .api }

145

class CodeBlockError:

146

"""Error information for code blocks that failed to parse or format."""

147

148

def __init__(self, offset: int, exc: Exception) -> None:

149

"""

150

Initialize error with location and exception details.

151

152

Parameters:

153

- offset: int - Character offset in source where error occurred

154

- exc: Exception - The underlying parsing or formatting exception

155

"""

156

157

offset: int # Character position where error occurred

158

exc: Exception # The underlying exception

159

```

160

161

## Supported Documentation Formats

162

163

### Markdown

164

165

Python code blocks:

166

```markdown

167

```python

168

def example():

169

print("Hello, world!")

170

```

171

```

172

173

Python console blocks:

174

```markdown

175

```pycon

176

>>> def example():

177

... print("Hello, world!")

178

...

179

>>> example()

180

Hello, world!

181

```

182

```

183

184

Control formatting with comments:

185

```markdown

186

<!-- blacken-docs:off -->

187

```python

188

# This code block will not be formatted

189

def example( ):

190

pass

191

```

192

<!-- blacken-docs:on -->

193

```

194

195

### reStructuredText

196

197

Python code blocks:

198

```rst

199

.. code-block:: python

200

201

def example():

202

print("Hello, world!")

203

```

204

205

Python console blocks:

206

```rst

207

.. code-block:: pycon

208

209

>>> def example():

210

... print("Hello, world!")

211

...

212

```

213

214

Literal blocks (with `--rst-literal-blocks` flag):

215

```rst

216

An example::

217

218

def example():

219

print("Hello, world!")

220

```

221

222

Control formatting with comments:

223

```rst

224

.. blacken-docs:off

225

226

.. code-block:: python

227

228

# This code block will not be formatted

229

def example( ):

230

pass

231

232

.. blacken-docs:on

233

```

234

235

### LaTeX

236

237

Minted Python blocks:

238

```latex

239

\begin{minted}{python}

240

def example():

241

print("Hello, world!")

242

\end{minted}

243

```

244

245

Minted Python console blocks:

246

```latex

247

\begin{minted}{pycon}

248

>>> def example():

249

... print("Hello, world!")

250

...

251

\end{minted}

252

```

253

254

PythonTeX blocks:

255

```latex

256

\begin{pycode}

257

def example():

258

print("Hello, world!")

259

\end{pycode}

260

```

261

262

Control formatting with comments:

263

```latex

264

% blacken-docs:off

265

\begin{minted}{python}

266

# This code block will not be formatted

267

def example( ):

268

pass

269

\end{minted}

270

% blacken-docs:on

271

```

272

273

## Command Line Options

274

275

### Black Pass-through Options

276

277

These options are passed directly to Black for code formatting:

278

279

- `-l, --line-length INT` - Set maximum line length (default: 88)

280

- `--preview` - Enable Black's preview features

281

- `-S, --skip-string-normalization` - Skip string quote normalization

282

- `-t, --target-version {py39,py310,py311,py312,py313}` - Set Python target version

283

- `--pyi` - Format as Python stub (.pyi) file

284

285

### blacken-docs Specific Options

286

287

- `--check` - Check-only mode: don't modify files, just report if changes needed

288

- `-E, --skip-errors` - Skip syntax errors from Black and continue processing

289

- `--rst-literal-blocks` - Also format literal blocks in reStructuredText files

290

291

### Examples

292

293

Format with custom line length:

294

```bash

295

blacken-docs -l 120 README.md

296

```

297

298

Check mode (don't modify files):

299

```bash

300

blacken-docs --check docs/*.rst

301

```

302

303

Skip errors and format literal blocks:

304

```bash

305

blacken-docs -E --rst-literal-blocks documentation.rst

306

```

307

308

Target specific Python version:

309

```bash

310

blacken-docs -t py311 examples.md

311

```

312

313

## Integration Patterns

314

315

### Pre-commit Hook

316

317

Add to `.pre-commit-config.yaml`:

318

319

```yaml

320

repos:

321

- repo: https://github.com/adamchainz/blacken-docs

322

rev: "1.19.1" # Use the latest version

323

hooks:

324

- id: blacken-docs

325

additional_dependencies:

326

- black==24.8.0 # Pin Black version

327

```

328

329

### Programmatic Integration

330

331

```python

332

import blacken_docs

333

import black

334

from pathlib import Path

335

336

def format_documentation_files(file_paths, line_length=88):

337

"""Format Python code blocks in multiple documentation files."""

338

# Note: black.Mode is used internally by blacken-docs

339

black_mode = black.Mode(line_length=line_length)

340

results = {}

341

342

for file_path in file_paths:

343

try:

344

exit_code = blacken_docs.format_file(

345

filename=str(file_path),

346

black_mode=black_mode,

347

skip_errors=False,

348

rst_literal_blocks=True,

349

check_only=False

350

)

351

results[file_path] = {

352

'success': exit_code != 2,

353

'modified': exit_code == 1

354

}

355

except Exception as e:

356

results[file_path] = {'success': False, 'error': str(e)}

357

358

return results

359

360

# Usage

361

doc_files = Path('docs').glob('*.md')

362

results = format_documentation_files(doc_files)

363

```

364

365

## Types

366

367

```python { .api }

368

# From black module (external dependency)

369

class black.FileMode:

370

"""Black formatting configuration."""

371

def __init__(

372

self,

373

target_versions: set[TargetVersion] = ...,

374

line_length: int = 88,

375

string_normalization: bool = True,

376

is_pyi: bool = False,

377

preview: bool = False

378

): ...

379

380

# Note: black.Mode is an alias for black.FileMode used in implementation

381

black.Mode = black.FileMode

382

383

class black.TargetVersion:

384

"""Python version targets for Black formatting."""

385

PY39: TargetVersion

386

PY310: TargetVersion

387

PY311: TargetVersion

388

PY312: TargetVersion

389

PY313: TargetVersion

390

391

# Standard library types used

392

from collections.abc import Sequence

393

```

394

395

## Error Cases

396

397

Common error scenarios and handling:

398

399

- **Syntax Errors**: Invalid Python code in blocks raises exceptions, captured in CodeBlockError objects

400

- **File Not Found**: format_file raises standard Python file exceptions

401

- **Permission Errors**: File write permissions cause standard I/O exceptions

402

- **Black Formatting Errors**: Internal Black errors are captured and reported with line numbers

403

404

Use `skip_errors=True` in format_file or `-E` flag to continue processing despite syntax errors in code blocks.