Unified markdown processor powered by plugins with parsing, transformation, and stringification capabilities
npx @tessl/cli install tessl/npm-remark@15.0.00
# Remark
1
2
Remark is a unified markdown processor powered by plugins that provides parsing, transformation, and stringification capabilities for markdown documents. It exports a single pre-configured unified processor that combines remark-parse and remark-stringify into a ready-to-use markdown processing pipeline.
3
4
## Package Information
5
6
- **Package Name**: remark
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install remark`
10
11
## Core Imports
12
13
```typescript
14
import { remark } from "remark";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { remark } = require("remark");
21
```
22
23
## Basic Usage
24
25
```typescript
26
import { remark } from "remark";
27
28
// Process markdown through complete pipeline
29
const file = await remark.process("# Hello World\n\nThis is **markdown**.");
30
console.log(String(file)); // "# Hello World\n\nThis is **markdown**.\n"
31
32
// Parse markdown to AST
33
const tree = remark.parse("# Hello World");
34
console.log(tree.type); // "root"
35
36
// Add plugins for extended functionality
37
const processor = remark
38
.use(remarkGfm) // Add GitHub Flavored Markdown support
39
.use(remarkToc, { heading: "Contents" }); // Add table of contents
40
41
const result = await processor.process(markdownContent);
42
```
43
44
## Architecture
45
46
Remark is built on the unified ecosystem and provides:
47
48
- **Pre-configured Processor**: A frozen unified processor combining remark-parse and remark-stringify
49
- **Plugin System**: Extensible architecture for adding markdown processing capabilities through unified
50
- **MDAST Integration**: Works with MDAST (Markdown Abstract Syntax Tree) format from @types/mdast
51
- **VFile Support**: Enhanced file handling with metadata and error reporting through vfile
52
- **Frozen Interface**: Immutable processor pattern preventing further configuration after creation
53
54
## Capabilities
55
56
### Main Export
57
58
The remark package exports a single pre-configured unified processor.
59
60
```typescript { .api }
61
/**
62
* Pre-configured unified processor with remark-parse and remark-stringify
63
* This is a frozen processor instance, not a function
64
*/
65
const remark: Processor<Root, undefined, undefined, Root, string>;
66
```
67
68
### Processing Methods
69
70
All processing methods are inherited from the unified processor interface:
71
72
#### Process Pipeline
73
74
Process markdown through the complete pipeline (parse → transform → stringify).
75
76
```typescript { .api }
77
/**
78
* Process markdown input through complete pipeline
79
* @param file - Markdown string or VFile to process
80
* @returns Promise resolving to processed VFile
81
*/
82
remark.process(file: string | VFile): Promise<VFile>;
83
84
/**
85
* Synchronous version of process()
86
* @param file - Markdown string or VFile to process
87
* @returns Processed VFile
88
*/
89
remark.processSync(file: string | VFile): VFile;
90
```
91
92
#### Parse Operations
93
94
Parse markdown to MDAST abstract syntax tree.
95
96
```typescript { .api }
97
/**
98
* Parse markdown to MDAST AST
99
* @param file - Markdown string or VFile to parse
100
* @returns MDAST Root node
101
*/
102
remark.parse(file: string | VFile): Root;
103
```
104
105
#### Stringify Operations
106
107
Convert MDAST abstract syntax tree to markdown string.
108
109
```typescript { .api }
110
/**
111
* Convert MDAST AST to markdown string
112
* @param tree - MDAST Root node to stringify
113
* @param file - Optional VFile for context
114
* @returns Markdown string
115
*/
116
remark.stringify(tree: Root, file?: VFile): string;
117
```
118
119
#### Transform Operations
120
121
Run transformation plugins on MDAST abstract syntax tree.
122
123
```typescript { .api }
124
/**
125
* Run transformation plugins on AST
126
* @param tree - MDAST Root node to transform
127
* @param file - Optional VFile for context
128
* @returns Promise resolving to transformed Root node
129
*/
130
remark.run(tree: Root, file?: VFile): Promise<Root>;
131
132
/**
133
* Synchronous version of run()
134
* @param tree - MDAST Root node to transform
135
* @param file - Optional VFile for context
136
* @returns Transformed Root node
137
*/
138
remark.runSync(tree: Root, file?: VFile): Root;
139
```
140
141
### Plugin Management
142
143
#### Plugin Registration
144
145
Add plugins or presets to extend processor capabilities.
146
147
```typescript { .api }
148
/**
149
* Add plugin to processor
150
* @param plugin - Plugin function to add
151
* @param options - Optional plugin configuration
152
* @returns New processor instance with plugin added
153
*/
154
remark.use(plugin: Plugin, options?: any): Processor<Root, undefined, undefined, Root, string>;
155
156
/**
157
* Add preset to processor
158
* @param preset - Plugin preset to add
159
* @returns New processor instance with preset added
160
*/
161
remark.use(preset: Preset): Processor<Root, undefined, undefined, Root, string>;
162
163
/**
164
* Add list of plugins to processor
165
* @param list - Array of plugins/presets to add
166
* @returns New processor instance with plugins added
167
*/
168
remark.use(list: PluggableList): Processor<Root, undefined, undefined, Root, string>;
169
```
170
171
### Configuration Management
172
173
#### Data Storage
174
175
Get or set processor configuration data and settings.
176
177
```typescript { .api }
178
/**
179
* Get configuration value
180
* @param key - Configuration key to retrieve
181
* @returns Configuration value
182
*/
183
remark.data(key: string): any;
184
185
/**
186
* Set configuration value
187
* @param key - Configuration key to set
188
* @param value - Configuration value to set
189
* @returns Processor instance for chaining
190
*/
191
remark.data(key: string, value: any): Processor<Root, undefined, undefined, Root, string>;
192
193
/**
194
* Set multiple configuration values
195
* @param dataset - Object containing configuration key-value pairs
196
* @returns Processor instance for chaining
197
*/
198
remark.data(dataset: Record<string, any>): Processor<Root, undefined, undefined, Root, string>;
199
```
200
201
#### Extension Configuration
202
203
Configure remark-parse and remark-stringify extensions via data.
204
205
```typescript { .api }
206
/**
207
* Configure micromark extensions for parsing
208
* Used by remark-parse to extend markdown syntax
209
*/
210
remark.data("micromarkExtensions", extensions: MicromarkExtension[]): Processor;
211
212
/**
213
* Configure fromMarkdown extensions for parsing
214
* Used by remark-parse to handle extended syntax nodes
215
*/
216
remark.data("fromMarkdownExtensions", extensions: FromMarkdownExtension[]): Processor;
217
218
/**
219
* Configure toMarkdown extensions for stringification
220
* Used by remark-stringify to output extended syntax
221
*/
222
remark.data("toMarkdownExtensions", extensions: ToMarkdownExtension[]): Processor;
223
224
/**
225
* Configure stringify settings
226
* Used by remark-stringify for output formatting
227
*/
228
remark.data("settings", settings: StringifySettings): Processor;
229
```
230
231
#### Processor Properties
232
233
```typescript { .api }
234
/**
235
* Create frozen processor instance (prevents further .use() calls)
236
* @returns Frozen processor instance
237
*/
238
remark.freeze(): Processor<Root, undefined, undefined, Root, string>;
239
240
/**
241
* Whether processor is frozen (always true for remark export)
242
*/
243
readonly remark.frozen: boolean;
244
```
245
246
## Types
247
248
### Core Types from Dependencies
249
250
Remark works with types from its dependencies:
251
252
```typescript { .api }
253
/**
254
* MDAST root node representing markdown document
255
* From @types/mdast package
256
*/
257
interface Root {
258
type: "root";
259
children: Array<RootContent>;
260
position?: Position;
261
}
262
263
/**
264
* Virtual file with path, content, and metadata
265
* From vfile package
266
*/
267
interface VFile {
268
readonly path?: string;
269
value: string;
270
readonly data: Record<string, unknown>;
271
readonly messages: Array<VFileMessage>;
272
readonly history: Array<string>;
273
readonly cwd: string;
274
}
275
276
/**
277
* Unified processor interface
278
* From unified package
279
*/
280
interface Processor<ParseTree, HeadTree, TailTree, CompileTree, CompileResult> {
281
parse(file: string | VFile): ParseTree;
282
stringify(tree: CompileTree, file?: VFile): CompileResult;
283
run(tree: HeadTree, file?: VFile): Promise<TailTree>;
284
runSync(tree: HeadTree, file?: VFile): TailTree;
285
process(file: string | VFile): Promise<VFile>;
286
processSync(file: string | VFile): VFile;
287
use(plugin: Plugin, options?: any): Processor<ParseTree, HeadTree, TailTree, CompileTree, CompileResult>;
288
data(key: string): any;
289
data(key: string, value: any): Processor<ParseTree, HeadTree, TailTree, CompileTree, CompileResult>;
290
freeze(): Processor<ParseTree, HeadTree, TailTree, CompileTree, CompileResult>;
291
readonly frozen: boolean;
292
}
293
294
/**
295
* Plugin function type
296
* From unified package
297
*/
298
type Plugin = (this: Processor, options?: any) => void | Transformer;
299
300
/**
301
* Transformation function type
302
* From unified package
303
*/
304
type Transformer = (tree: Node, file?: VFile) => void | Node | Promise<void | Node>;
305
306
/**
307
* Plugin or plugin tuple type
308
* From unified package
309
*/
310
type Pluggable = Plugin | [Plugin, any] | Preset;
311
312
/**
313
* List of pluggables
314
* From unified package
315
*/
316
type PluggableList = Array<Pluggable>;
317
318
/**
319
* Plugin preset configuration
320
* From unified package
321
*/
322
interface Preset {
323
settings?: Record<string, any>;
324
plugins?: PluggableList;
325
}
326
```
327
328
### Extension Types
329
330
```typescript { .api }
331
/**
332
* Micromark extension for parsing
333
* From micromark package
334
*/
335
interface MicromarkExtension {
336
document?: Record<string, any>;
337
contentInitial?: Record<string, any>;
338
flowInitial?: Record<string, any>;
339
flow?: Record<string, any>;
340
string?: Record<string, any>;
341
text?: Record<string, any>;
342
}
343
344
/**
345
* FromMarkdown extension for AST construction
346
* From mdast-util-from-markdown package
347
*/
348
interface FromMarkdownExtension {
349
canContainEols?: Array<string>;
350
enter?: Record<string, any>;
351
exit?: Record<string, any>;
352
}
353
354
/**
355
* ToMarkdown extension for stringification
356
* From mdast-util-to-markdown package
357
*/
358
interface ToMarkdownExtension {
359
extensions?: Array<any>;
360
}
361
```
362
363
## Configuration Options
364
365
### Stringify Settings
366
367
Configure markdown output formatting via the settings data key:
368
369
```typescript
370
remark.data("settings", {
371
bullet: "*", // Bullet list marker ("-", "*", "+")
372
bulletOrdered: ".", // Ordered list marker (".", ")")
373
closeAtx: false, // Close ATX headings with #
374
emphasis: "*", // Emphasis marker ("*", "_")
375
fence: "`", // Code fence marker ("`", "~")
376
fences: true, // Use fences for code blocks
377
incrementListMarker: true, // Increment ordered list markers
378
listItemIndent: "one", // List indentation ("tab", "one", "mixed")
379
quote: '"', // Quote marker for titles ('"', "'")
380
rule: "*", // Horizontal rule marker ("-", "*", "_")
381
ruleRepetition: 3, // HR marker repetition count
382
ruleSpaces: false, // Spaces around HR markers
383
setext: false, // Use setext headings (underlined)
384
strong: "*", // Strong emphasis marker ("*", "_")
385
tightDefinitions: false // Tight definition formatting
386
});
387
```
388
389
### Extension Configuration
390
391
```typescript
392
// Add micromark extensions for parsing
393
remark.data("micromarkExtensions", [gfmExtension]);
394
395
// Add fromMarkdown extensions for AST handling
396
remark.data("fromMarkdownExtensions", [gfmFromMarkdown]);
397
398
// Add toMarkdown extensions for stringification
399
remark.data("toMarkdownExtensions", [gfmToMarkdown]);
400
```
401
402
## Usage Examples
403
404
### Basic Processing
405
406
```typescript
407
import { remark } from "remark";
408
409
// Simple processing
410
const file = await remark.process("# Hello\n\nWorld!");
411
console.log(String(file)); // "# Hello\n\nWorld!\n"
412
```
413
414
### With Plugins
415
416
```typescript
417
import { remark } from "remark";
418
import remarkGfm from "remark-gfm";
419
import remarkToc from "remark-toc";
420
421
const processor = remark
422
.use(remarkGfm)
423
.use(remarkToc, { heading: "contents", tight: true });
424
425
const result = await processor.process(markdownWithTables);
426
```
427
428
### Custom Configuration
429
430
```typescript
431
import { remark } from "remark";
432
433
const processor = remark
434
.data("settings", {
435
bulletOrdered: ")",
436
incrementListMarker: false,
437
setext: true,
438
emphasis: "_"
439
});
440
441
const formatted = await processor.process(inputMarkdown);
442
```
443
444
### AST Manipulation
445
446
```typescript
447
import { remark } from "remark";
448
import type { Root } from "mdast";
449
450
// Parse to AST
451
const tree = remark.parse("# Hello World") as Root;
452
453
// Modify AST
454
tree.children.push({
455
type: "paragraph",
456
children: [{ type: "text", value: "Added content" }]
457
});
458
459
// Convert back to markdown
460
const markdown = remark.stringify(tree);
461
```
462
463
### Extension Usage
464
465
```typescript
466
import { remark } from "remark";
467
import { gfm } from "micromark-extension-gfm";
468
import { gfmFromMarkdown, gfmToMarkdown } from "mdast-util-gfm";
469
470
const processor = remark
471
.data("micromarkExtensions", [gfm()])
472
.data("fromMarkdownExtensions", [gfmFromMarkdown()])
473
.data("toMarkdownExtensions", [gfmToMarkdown()]);
474
475
const result = await processor.process("| Column 1 | Column 2 |\n|----------|----------|\n| Cell 1 | Cell 2 |");
476
```