or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdcustom-nodes.mddocumenters.mdindex.mdplugin-system.mdyaml-types.md

plugin-system.mddocs/

0

# Plugin Development System

1

2

Extensible plugin architecture for customizing API Documenter's markdown documentation generation. The plugin system enables custom page processing, content modification, and integration with external tools while maintaining compatibility with the core documentation workflow.

3

4

## Capabilities

5

6

### Plugin Manifest Structure

7

8

Define plugins by exporting a manifest that declares available features.

9

10

```typescript { .api }

11

interface IApiDocumenterPluginManifest {

12

manifestVersion: 1000;

13

features: IFeatureDefinition[];

14

}

15

16

interface IFeatureDefinition {

17

featureName: string;

18

kind: 'MarkdownDocumenterFeature';

19

subclass: { new (initialization: PluginFeatureInitialization): MarkdownDocumenterFeature };

20

}

21

```

22

23

**Plugin Package Structure:**

24

25

```typescript

26

// my-documenter-plugin/src/index.ts

27

import {

28

MarkdownDocumenterFeature,

29

IApiDocumenterPluginManifest,

30

PluginFeatureInitialization

31

} from "@microsoft/api-documenter";

32

33

class CustomMarkdownFeature extends MarkdownDocumenterFeature {

34

public onInitialized(): void {

35

console.log('Plugin initialized');

36

}

37

}

38

39

export const apiDocumenterPluginManifest: IApiDocumenterPluginManifest = {

40

manifestVersion: 1000,

41

features: [

42

{

43

featureName: 'custom-markdown-processor',

44

kind: 'MarkdownDocumenterFeature',

45

subclass: CustomMarkdownFeature

46

}

47

]

48

};

49

```

50

51

### MarkdownDocumenterFeature

52

53

Base class for creating markdown documentation plugins with lifecycle hooks.

54

55

```typescript { .api }

56

abstract class MarkdownDocumenterFeature extends PluginFeature {

57

context!: MarkdownDocumenterFeatureContext;

58

59

/**

60

* Called before each markdown file is written, allowing content customization

61

* @param eventArgs - Event arguments with page content and metadata

62

*/

63

onBeforeWritePage(eventArgs: IMarkdownDocumenterFeatureOnBeforeWritePageArgs): void;

64

65

/**

66

* Called after all output files have been written

67

* @param eventArgs - Event arguments for completion phase

68

*/

69

onFinished(eventArgs: IMarkdownDocumenterFeatureOnFinishedArgs): void;

70

}

71

72

interface IMarkdownDocumenterFeatureOnBeforeWritePageArgs {

73

readonly apiItem: ApiItem;

74

pageContent: string;

75

readonly outputFilename: string;

76

}

77

78

interface IMarkdownDocumenterFeatureOnFinishedArgs {}

79

```

80

81

**Plugin Development Example:**

82

83

```typescript

84

import {

85

MarkdownDocumenterFeature,

86

IMarkdownDocumenterFeatureOnBeforeWritePageArgs

87

} from "@microsoft/api-documenter";

88

89

class CustomStyleFeature extends MarkdownDocumenterFeature {

90

public onBeforeWritePage(eventArgs: IMarkdownDocumenterFeatureOnBeforeWritePageArgs): void {

91

// Add custom CSS classes to headings

92

eventArgs.pageContent = eventArgs.pageContent.replace(

93

/^## (.+)$/gm,

94

'## $1 {.api-heading}'

95

);

96

97

// Add navigation footer

98

if (eventArgs.apiItem.kind === 'Class') {

99

eventArgs.pageContent += '\n\n---\n\n[Back to API Reference](./index.md)';

100

}

101

}

102

103

public onFinished(): void {

104

console.log('Documentation generation completed with custom styling');

105

}

106

}

107

```

108

109

### MarkdownDocumenterFeatureContext

110

111

Context object providing access to the API model and documenter functionality.

112

113

```typescript { .api }

114

class MarkdownDocumenterFeatureContext {

115

/**

116

* Provides access to the ApiModel for the documentation being generated

117

*/

118

readonly apiModel: ApiModel;

119

120

/**

121

* The full path to the output folder

122

*/

123

readonly outputFolder: string;

124

125

/**

126

* Exposes functionality of the documenter

127

*/

128

readonly documenter: MarkdownDocumenterAccessor;

129

130

constructor(options: MarkdownDocumenterFeatureContext);

131

}

132

```

133

134

### MarkdownDocumenterAccessor

135

136

Provides access to documenter functionality for plugins.

137

138

```typescript { .api }

139

class MarkdownDocumenterAccessor {

140

/**

141

* For a given ApiItem, return its markdown hyperlink

142

* @param apiItem - The API item to get a link for

143

* @returns The hyperlink, or undefined if the ApiItem does not have a hyperlink

144

*/

145

getLinkForApiItem(apiItem: ApiItem): string | undefined;

146

}

147

```

148

149

**Usage Example:**

150

151

```typescript

152

class CrossReferenceFeature extends MarkdownDocumenterFeature {

153

public onBeforeWritePage(eventArgs: IMarkdownDocumenterFeatureOnBeforeWritePageArgs): void {

154

// Add cross-references to related API items

155

const relatedItems = this.findRelatedItems(eventArgs.apiItem);

156

157

if (relatedItems.length > 0) {

158

let seeAlsoSection = '\n\n## See Also\n\n';

159

160

for (const item of relatedItems) {

161

const link = this.context.documenter.getLinkForApiItem(item);

162

if (link) {

163

seeAlsoSection += `- [${item.displayName}](${link})\n`;

164

}

165

}

166

167

eventArgs.pageContent += seeAlsoSection;

168

}

169

}

170

}

171

```

172

173

### Plugin Base Classes

174

175

Core plugin infrastructure classes.

176

177

```typescript { .api }

178

abstract class PluginFeature {

179

/**

180

* Exposes various services that can be used by a plugin

181

*/

182

context: PluginFeatureContext;

183

184

/**

185

* @param initialization - Plugin initialization object

186

*/

187

constructor(initialization: PluginFeatureInitialization);

188

189

/**

190

* Called after the feature is initialized, but before any processing occurs

191

*/

192

onInitialized(): void;

193

}

194

195

class PluginFeatureContext {}

196

197

class PluginFeatureInitialization {

198

constructor();

199

}

200

```

201

202

## Plugin Configuration

203

204

### Loading Plugins

205

206

Plugins are loaded via configuration in the `api-documenter.json` file:

207

208

```json { .api }

209

{

210

"configFormatVersion": "1.0",

211

"plugins": [

212

{

213

"packageName": "my-documenter-plugin",

214

"enabled": true,

215

"options": {

216

"customOption": "value"

217

}

218

}

219

]

220

}

221

```

222

223

### Plugin Package Requirements

224

225

1. **NPM Package**: Plugin must be a valid NPM package with prefix `doc-plugin-`

226

2. **Main Export**: Package must export `apiDocumenterPluginManifest` object

227

3. **Dependencies**: Include `@microsoft/api-documenter` as peer dependency

228

4. **TypeScript**: Recommended for type safety and IDE support

229

230

**package.json Example:**

231

232

```json

233

{

234

"name": "doc-plugin-custom-styles",

235

"version": "1.0.0",

236

"main": "lib/index.js",

237

"peerDependencies": {

238

"@microsoft/api-documenter": "^7.26.0"

239

}

240

}

241

```

242

243

## Advanced Plugin Patterns

244

245

### Content Transformation

246

247

```typescript

248

class ContentTransformFeature extends MarkdownDocumenterFeature {

249

public onBeforeWritePage(eventArgs: IMarkdownDocumenterFeatureOnBeforeWritePageArgs): void {

250

// Transform code blocks to add syntax highlighting

251

eventArgs.pageContent = eventArgs.pageContent.replace(

252

/```typescript/g,

253

'```typescript {.line-numbers}'

254

);

255

256

// Add custom metadata to frontmatter

257

if (eventArgs.pageContent.startsWith('# ')) {

258

const title = eventArgs.pageContent.match(/^# (.+)$/m)?.[1];

259

eventArgs.pageContent = `---\ntitle: ${title}\napiItem: ${eventArgs.apiItem.kind}\n---\n\n${eventArgs.pageContent}`;

260

}

261

}

262

}

263

```

264

265

### Integration with External Tools

266

267

```typescript

268

class ExternalIntegrationFeature extends MarkdownDocumenterFeature {

269

public onFinished(): void {

270

// Generate search index

271

this.generateSearchIndex();

272

273

// Upload to documentation hosting service

274

this.uploadToHostingService();

275

}

276

277

private generateSearchIndex(): void {

278

// Implementation for search index generation

279

}

280

281

private uploadToHostingService(): void {

282

// Implementation for uploading docs

283

}

284

}

285

```

286

287

## Error Handling

288

289

Plugin errors are handled gracefully by the core system:

290

291

- **Plugin Load Failures**: Detailed error messages with plugin name and reason

292

- **Runtime Exceptions**: Plugins that throw exceptions during execution are disabled

293

- **Configuration Errors**: Clear validation messages for malformed plugin configurations

294

- **Missing Dependencies**: Informative messages when plugin dependencies are not found