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