or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mddocstring-processing.mddocumentation-rendering.mdindex.mdmain-config.mdplugin-interfaces.mdpython-loading.mdutility-functions.md

plugin-interfaces.mddocs/

0

# Plugin Interfaces

1

2

Abstract interfaces and base classes that define the plugin architecture for loaders, processors, renderers, and additional functionality like source linking and development servers.

3

4

## Capabilities

5

6

### Core Interfaces

7

8

Base interfaces that form the foundation of pydoc-markdown's plugin system.

9

10

```python { .api }

11

class Context:

12

"""

13

Context data passed to plugins during initialization.

14

15

Attributes:

16

directory: Working directory for plugin operations

17

"""

18

directory: str

19

20

def __init__(self, directory: str) -> None:

21

"""

22

Initialize context with working directory.

23

24

Args:

25

directory: Working directory path

26

"""

27

28

class PluginBase(ABC):

29

"""

30

Abstract base class for all pydoc-markdown plugins.

31

32

Provides basic plugin lifecycle management.

33

"""

34

35

def init(self, context: Context) -> None:

36

"""

37

Initialize plugin with context data.

38

39

Args:

40

context: Context containing directory and other initialization data

41

"""

42

```

43

44

### Loader Interface

45

46

Interface for loading documentation data from various sources.

47

48

```python { .api }

49

class Loader(PluginBase):

50

"""

51

Interface for loading documentation data.

52

53

Loaders extract API information from source code, documentation files,

54

or other sources and convert them into docspec.Module objects.

55

"""

56

57

def load(self) -> Iterable[docspec.Module]:

58

"""

59

Load documentation data.

60

61

Returns:

62

Iterable of docspec.Module objects containing API information

63

64

Raises:

65

LoaderError: If loading fails

66

"""

67

68

class LoaderError(Exception):

69

"""Exception raised when loader operations fail."""

70

```

71

72

### Processor Interface

73

74

Interface for transforming and enhancing loaded documentation data.

75

76

```python { .api }

77

class Processor(PluginBase):

78

"""

79

Interface for processing and transforming docspec.Module objects.

80

81

Processors typically modify docstrings, filter content, resolve references,

82

or apply other transformations to prepare data for rendering.

83

"""

84

85

def process(self, modules: List[docspec.Module], resolver: Optional[Resolver]) -> None:

86

"""

87

Process modules in place.

88

89

Args:

90

modules: List of modules to process (modified in place)

91

resolver: Optional resolver for handling cross-references

92

"""

93

```

94

95

### Renderer Interface

96

97

Interface for generating documentation output in various formats.

98

99

```python { .api }

100

class Renderer(PluginBase):

101

"""

102

Interface for rendering docspec.Module objects to output files.

103

104

Renderers generate final documentation in formats like Markdown, HTML,

105

or integration with static site generators.

106

"""

107

108

def process(self, modules: List[docspec.Module], resolver: Optional[Resolver]) -> None:

109

"""

110

Optional processing step before rendering.

111

112

Args:

113

modules: List of modules to process

114

resolver: Optional resolver for cross-references

115

"""

116

117

def get_resolver(self, modules: List[docspec.Module]) -> Optional[Resolver]:

118

"""

119

Get resolver for cross-reference handling.

120

121

Args:

122

modules: List of modules for resolver context

123

124

Returns:

125

Resolver instance or None if not supported

126

"""

127

128

def render(self, modules: List[docspec.Module]) -> None:

129

"""

130

Render modules to output format.

131

132

Args:

133

modules: List of modules to render

134

"""

135

```

136

137

### Resolver Interfaces

138

139

Interfaces for resolving cross-references between API objects.

140

141

```python { .api }

142

class Resolver(ABC):

143

"""

144

Interface for resolving cross-references to hyperlinks.

145

146

Used by processors to convert references in docstrings to URLs or other

147

link formats appropriate for the target documentation format.

148

"""

149

150

def resolve_ref(self, scope: docspec.ApiObject, ref: str) -> Optional[str]:

151

"""

152

Resolve reference to a hyperlink.

153

154

Args:

155

scope: API object containing the reference

156

ref: Reference string to resolve

157

158

Returns:

159

Resolved hyperlink or None if resolution fails

160

"""

161

162

class ResolverV2(ABC):

163

"""

164

New-style resolver interface that returns resolved objects directly.

165

166

Provides more flexibility than the original Resolver interface by

167

returning the actual resolved API object instead of a string representation.

168

"""

169

170

def resolve_reference(self, suite: ApiSuite, scope: docspec.ApiObject, ref: str) -> Optional[docspec.ApiObject]:

171

"""

172

Resolve reference to an API object.

173

174

Args:

175

suite: API suite containing all available objects

176

scope: API object containing the reference

177

ref: Reference string to resolve

178

179

Returns:

180

Resolved API object or None if resolution fails

181

"""

182

```

183

184

### Additional Renderer Interfaces

185

186

Specialized renderer interfaces for specific rendering capabilities.

187

188

```python { .api }

189

class SinglePageRenderer(PluginBase):

190

"""

191

Interface for renderers that can generate single-page output.

192

"""

193

194

def render_single_page(

195

self,

196

fp: TextIO,

197

modules: List[docspec.Module],

198

page_title: Optional[str] = None

199

) -> None:

200

"""

201

Render modules to a single page.

202

203

Args:

204

fp: File object to write output to

205

modules: List of modules to render

206

page_title: Optional title for the page

207

"""

208

209

class SingleObjectRenderer(PluginBase):

210

"""

211

Interface for renderers that can render individual API objects.

212

"""

213

214

def render_object(self, fp: TextIO, obj: docspec.ApiObject, options: Dict[str, Any]) -> None:

215

"""

216

Render a single API object.

217

218

Args:

219

fp: File object to write output to

220

obj: API object to render

221

options: Rendering options and configuration

222

"""

223

```

224

225

### Server Interface

226

227

Interface for development server functionality.

228

229

```python { .api }

230

class Server(ABC):

231

"""

232

Interface for development server capabilities.

233

234

Renderers implementing this interface can provide live preview

235

functionality with automatic reloading when source files change.

236

"""

237

238

def get_server_url(self) -> str:

239

"""

240

Get the development server URL.

241

242

Returns:

243

URL where the development server is accessible

244

"""

245

246

def start_server(self) -> subprocess.Popen:

247

"""

248

Start the development server process.

249

250

Returns:

251

Process handle for the running server

252

"""

253

254

def reload_server(self, process: subprocess.Popen) -> subprocess.Popen:

255

"""

256

Reload server process when files change.

257

258

Args:

259

process: Current server process

260

261

Returns:

262

New server process or same process if reload not needed

263

"""

264

```

265

266

### Builder Interface

267

268

Interface for build functionality after rendering.

269

270

```python { .api }

271

class Builder(ABC):

272

"""

273

Interface for renderers that support building final output.

274

275

Builders can generate final static sites, optimize output,

276

or perform other post-rendering operations.

277

"""

278

279

def build(self, site_dir: str) -> None:

280

"""

281

Build final output after rendering.

282

283

Args:

284

site_dir: Directory where build output should be placed

285

"""

286

```

287

288

### Source Linker Interface

289

290

Interface for linking documentation to source code.

291

292

```python { .api }

293

class SourceLinker(PluginBase):

294

"""

295

Interface for generating links to source code.

296

297

Source linkers determine URLs to the original source code for

298

API objects, enabling documentation to include "view source" links.

299

"""

300

301

def get_source_url(self, obj: docspec.ApiObject) -> Optional[str]:

302

"""

303

Get URL to source code for an API object.

304

305

Args:

306

obj: API object to get source URL for

307

308

Returns:

309

URL to source code or None if not available

310

"""

311

```

312

313

## Plugin Implementation Examples

314

315

### Custom Loader Example

316

317

```python

318

from pydoc_markdown.interfaces import Loader, Context

319

import docspec

320

321

class CustomLoader(Loader):

322

def __init__(self, source_path: str):

323

self.source_path = source_path

324

325

def init(self, context: Context) -> None:

326

# Initialize with context

327

self.working_dir = context.directory

328

329

def load(self) -> Iterable[docspec.Module]:

330

# Load from custom source

331

module = docspec.Module(

332

name="custom_module",

333

location=docspec.Location("custom.py", 1),

334

docstring="Custom loaded module"

335

)

336

return [module]

337

```

338

339

### Custom Processor Example

340

341

```python

342

from pydoc_markdown.interfaces import Processor, Resolver

343

import docspec

344

345

class CustomProcessor(Processor):

346

def __init__(self, transform_pattern: str):

347

self.transform_pattern = transform_pattern

348

349

def process(self, modules: List[docspec.Module], resolver: Optional[Resolver]) -> None:

350

for module in modules:

351

for obj in module.members:

352

if obj.docstring:

353

# Apply custom transformation

354

obj.docstring = obj.docstring.replace(

355

self.transform_pattern,

356

"**" + self.transform_pattern + "**"

357

)

358

```

359

360

### Custom Renderer Example

361

362

```python

363

from pydoc_markdown.interfaces import Renderer, Resolver

364

import docspec

365

366

class CustomRenderer(Renderer):

367

def __init__(self, output_file: str):

368

self.output_file = output_file

369

370

def render(self, modules: List[docspec.Module]) -> None:

371

with open(self.output_file, 'w') as f:

372

for module in modules:

373

f.write(f"# {module.name}\n\n")

374

if module.docstring:

375

f.write(f"{module.docstring}\n\n")

376

377

for obj in module.members:

378

f.write(f"## {obj.name}\n\n")

379

if obj.docstring:

380

f.write(f"{obj.docstring}\n\n")

381

```

382

383

### Custom Source Linker Example

384

385

```python

386

from pydoc_markdown.interfaces import SourceLinker

387

import docspec

388

389

class GitHubSourceLinker(SourceLinker):

390

def __init__(self, repo_url: str, branch: str = "main"):

391

self.repo_url = repo_url.rstrip('/')

392

self.branch = branch

393

394

def get_source_url(self, obj: docspec.ApiObject) -> Optional[str]:

395

if obj.location and obj.location.filename:

396

return f"{self.repo_url}/blob/{self.branch}/{obj.location.filename}#L{obj.location.lineno}"

397

return None

398

```

399

400

## Plugin Registration

401

402

Plugins are typically registered via entry points in setup.py or pyproject.toml:

403

404

### Poetry Configuration (pyproject.toml)

405

406

```toml

407

[tool.poetry.plugins."pydoc_markdown.interfaces.Loader"]

408

custom = "mypackage.loaders:CustomLoader"

409

410

[tool.poetry.plugins."pydoc_markdown.interfaces.Processor"]

411

custom = "mypackage.processors:CustomProcessor"

412

413

[tool.poetry.plugins."pydoc_markdown.interfaces.Renderer"]

414

custom = "mypackage.renderers:CustomRenderer"

415

416

[tool.poetry.plugins."pydoc_markdown.interfaces.SourceLinker"]

417

custom = "mypackage.linkers:CustomSourceLinker"

418

```

419

420

### Using Custom Plugins

421

422

```yaml

423

# pydoc-markdown.yml

424

loaders:

425

- type: custom

426

source_path: "/path/to/source"

427

428

processors:

429

- type: custom

430

transform_pattern: "TODO"

431

432

renderer:

433

type: custom

434

output_file: "custom-docs.md"

435

```

436

437

## Interface Compatibility

438

439

### Multiple Interface Implementation

440

441

Renderers can implement multiple interfaces for enhanced functionality:

442

443

```python

444

class AdvancedRenderer(Renderer, Server, Builder, SinglePageRenderer):

445

def render(self, modules: List[docspec.Module]) -> None:

446

# Standard rendering

447

pass

448

449

def get_server_url(self) -> str:

450

return "http://localhost:8000"

451

452

def start_server(self) -> subprocess.Popen:

453

# Start development server

454

pass

455

456

def build(self, site_dir: str) -> None:

457

# Build final output

458

pass

459

460

def render_single_page(self, fp: TextIO, modules: List[docspec.Module], page_title: Optional[str] = None) -> None:

461

# Single page rendering

462

pass

463

```

464

465

### Interface Detection

466

467

Check renderer capabilities at runtime:

468

469

```python

470

from pydoc_markdown.interfaces import Server, Builder

471

472

# Check if renderer supports server

473

if isinstance(renderer, Server):

474

server_url = renderer.get_server_url()

475

process = renderer.start_server()

476

477

# Check if renderer supports building

478

if isinstance(renderer, Builder):

479

renderer.build("/path/to/site/")

480

```