or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-milkdown--transformer

Bidirectional transformation library between markdown AST and ProseMirror document structures for the Milkdown editor

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@milkdown/transformer@7.15.x

To install, run

npx @tessl/cli install tessl/npm-milkdown--transformer@7.15.0

0

# @milkdown/transformer

1

2

@milkdown/transformer is a TypeScript library that provides bidirectional transformation between markdown AST and ProseMirror document structures. It serves as a critical bridge component in the Milkdown ecosystem, enabling seamless conversion between markdown source and the editor's internal document representation while maintaining semantic consistency and supporting extensible parser/serializer specifications.

3

4

## Package Information

5

6

- **Package Name**: @milkdown/transformer

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @milkdown/transformer`

10

11

## Core Imports

12

13

```typescript

14

import {

15

ParserState,

16

SerializerState,

17

Parser,

18

Serializer,

19

NodeParserSpec,

20

MarkParserSpec,

21

NodeSerializerSpec,

22

MarkSerializerSpec

23

} from "@milkdown/transformer";

24

```

25

26

For CommonJS:

27

28

```javascript

29

const {

30

ParserState,

31

SerializerState

32

} = require("@milkdown/transformer");

33

```

34

35

**External Dependencies:**

36

37

This package integrates with ProseMirror and remark. Key external types include:

38

39

```typescript

40

// From @milkdown/prose/model (ProseMirror types)

41

import type {

42

Schema, // ProseMirror schema definition

43

Node, // ProseMirror document node

44

NodeType, // ProseMirror node type

45

MarkType, // ProseMirror mark type

46

NodeSpec, // ProseMirror node specification

47

MarkSpec, // ProseMirror mark specification

48

Attrs, // Node/mark attributes object

49

Fragment, // Collection of ProseMirror nodes

50

Mark // ProseMirror mark instance

51

} from "@milkdown/prose/model";

52

53

// From remark ecosystem

54

import type { remark } from "remark";

55

import type { Plugin, Transformer } from "unified";

56

```

57

58

## Basic Usage

59

60

```typescript

61

import { ParserState, SerializerState } from "@milkdown/transformer";

62

import { remark } from "remark";

63

import { schema } from "@milkdown/prose/model";

64

65

// Create parser to convert markdown to ProseMirror

66

const parser = ParserState.create(schema, remark());

67

const prosemirrorDoc = parser("# Hello World\n\nThis is **bold** text.");

68

69

// Create serializer to convert ProseMirror to markdown

70

const serializer = SerializerState.create(schema, remark());

71

const markdown = serializer(prosemirrorDoc);

72

73

console.log(markdown); // "# Hello World\n\nThis is **bold** text."

74

```

75

76

## Architecture

77

78

@milkdown/transformer is built around several key components:

79

80

- **Parser System**: `ParserState` class providing a state machine for transforming markdown AST to ProseMirror nodes

81

- **Serializer System**: `SerializerState` class providing a state machine for transforming ProseMirror nodes to markdown AST

82

- **Specification System**: Interfaces for defining custom node and mark transformations (`NodeParserSpec`, `MarkParserSpec`, etc.)

83

- **Stack System**: Generic stack implementations for managing nested transformation contexts

84

- **Type System**: Comprehensive TypeScript interfaces and utilities for markdown and ProseMirror integration

85

86

## Capabilities

87

88

### Parser System

89

90

State machine and specification system for converting markdown AST into ProseMirror document structures with extensible node and mark processing.

91

92

```typescript { .api }

93

class ParserState extends Stack<Node, ParserStackElement> {

94

static create(schema: Schema, remark: RemarkParser): Parser;

95

injectRoot(node: MarkdownNode, nodeType: NodeType, attrs?: Attrs): ParserState;

96

openNode(nodeType: NodeType, attrs?: Attrs): ParserState;

97

closeNode(): ParserState;

98

addNode(nodeType: NodeType, attrs?: Attrs, content?: Node[]): ParserState;

99

openMark(markType: MarkType, attrs?: Attrs): ParserState;

100

closeMark(markType: MarkType): ParserState;

101

addText(text: string): ParserState;

102

next(nodes: MarkdownNode | MarkdownNode[]): ParserState;

103

toDoc(): Node;

104

run(remark: RemarkParser, markdown: string): ParserState;

105

}

106

107

type Parser = (text: string) => Node;

108

```

109

110

[Parser System](./parser.md)

111

112

### Serializer System

113

114

State machine and specification system for converting ProseMirror document structures into markdown AST with extensible node and mark processing.

115

116

```typescript { .api }

117

class SerializerState extends Stack<MarkdownNode, SerializerStackElement> {

118

static create(schema: Schema, remark: RemarkParser): Serializer;

119

openNode(type: string, value?: string, props?: JSONRecord): SerializerState;

120

closeNode(): SerializerState;

121

addNode(type: string, children?: MarkdownNode[], value?: string, props?: JSONRecord): SerializerState;

122

withMark(mark: Mark, type: string, value?: string, props?: JSONRecord): SerializerState;

123

closeMark(mark: Mark): SerializerState;

124

next(nodes: Node | Fragment): SerializerState;

125

toString(remark: RemarkParser): string;

126

run(tree: Node): SerializerState;

127

}

128

129

type Serializer = (content: Node) => string;

130

```

131

132

[Serializer System](./serializer.md)

133

134

### Specification System

135

136

Interfaces and types for defining custom transformation behavior between markdown and ProseMirror elements.

137

138

```typescript { .api }

139

interface NodeParserSpec {

140

match: (node: MarkdownNode) => boolean;

141

runner: (state: ParserState, node: MarkdownNode, proseType: NodeType) => void;

142

}

143

144

interface MarkParserSpec {

145

match: (node: MarkdownNode) => boolean;

146

runner: (state: ParserState, node: MarkdownNode, proseType: MarkType) => void;

147

}

148

149

interface NodeSerializerSpec {

150

match: (node: Node) => boolean;

151

runner: (state: SerializerState, node: Node) => void;

152

}

153

154

interface MarkSerializerSpec {

155

match: (mark: Mark) => boolean;

156

runner: (state: SerializerState, mark: Mark, node: Node) => void | boolean;

157

}

158

```

159

160

[Specification System](./specifications.md)

161

162

### Utility System

163

164

Base classes, type definitions, and utility functions for stack management and type safety.

165

166

```typescript { .api }

167

class Stack<Node, Element extends StackElement<Node>> {

168

size(): number;

169

top(): Element | undefined;

170

push(node: Node): void;

171

open(node: Element): void;

172

close(): Element;

173

}

174

175

abstract class StackElement<Node> {

176

abstract push(node: Node, ...rest: Node[]): void;

177

}

178

179

type RemarkParser = ReturnType<typeof remark>;

180

type MarkdownNode = Node & { children?: MarkdownNode[] };

181

```

182

183

[Utility System](./utilities.md)

184

185

## Types

186

187

```typescript { .api }

188

interface NodeSchema extends NodeSpec {

189

readonly toMarkdown: NodeSerializerSpec;

190

readonly parseMarkdown: NodeParserSpec;

191

readonly priority?: number;

192

}

193

194

interface MarkSchema extends MarkSpec {

195

readonly toMarkdown: MarkSerializerSpec;

196

readonly parseMarkdown: MarkParserSpec;

197

}

198

199

interface RemarkPlugin<T = Record<string, unknown>> {

200

plugin: Plugin<[T], Root>;

201

options: T;

202

}

203

204

type JSONRecord = Record<string, JSONValue>;

205

type JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };

206

```