or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdparser.mdserializer.mdspecifications.mdutilities.md
tile.json

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

index.mddocs/

@milkdown/transformer

@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.

Package Information

  • Package Name: @milkdown/transformer
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @milkdown/transformer

Core Imports

import { 
  ParserState, 
  SerializerState, 
  Parser, 
  Serializer,
  NodeParserSpec,
  MarkParserSpec,
  NodeSerializerSpec,
  MarkSerializerSpec
} from "@milkdown/transformer";

For CommonJS:

const { 
  ParserState, 
  SerializerState 
} = require("@milkdown/transformer");

External Dependencies:

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

// From @milkdown/prose/model (ProseMirror types)
import type { 
  Schema,    // ProseMirror schema definition
  Node,      // ProseMirror document node
  NodeType,  // ProseMirror node type
  MarkType,  // ProseMirror mark type
  NodeSpec,  // ProseMirror node specification
  MarkSpec,  // ProseMirror mark specification
  Attrs,     // Node/mark attributes object
  Fragment,  // Collection of ProseMirror nodes
  Mark       // ProseMirror mark instance
} from "@milkdown/prose/model";

// From remark ecosystem
import type { remark } from "remark";
import type { Plugin, Transformer } from "unified";

Basic Usage

import { ParserState, SerializerState } from "@milkdown/transformer";
import { remark } from "remark";
import { schema } from "@milkdown/prose/model";

// Create parser to convert markdown to ProseMirror
const parser = ParserState.create(schema, remark());
const prosemirrorDoc = parser("# Hello World\n\nThis is **bold** text.");

// Create serializer to convert ProseMirror to markdown
const serializer = SerializerState.create(schema, remark());
const markdown = serializer(prosemirrorDoc);

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

Architecture

@milkdown/transformer is built around several key components:

  • Parser System: ParserState class providing a state machine for transforming markdown AST to ProseMirror nodes
  • Serializer System: SerializerState class providing a state machine for transforming ProseMirror nodes to markdown AST
  • Specification System: Interfaces for defining custom node and mark transformations (NodeParserSpec, MarkParserSpec, etc.)
  • Stack System: Generic stack implementations for managing nested transformation contexts
  • Type System: Comprehensive TypeScript interfaces and utilities for markdown and ProseMirror integration

Capabilities

Parser System

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

class ParserState extends Stack<Node, ParserStackElement> {
  static create(schema: Schema, remark: RemarkParser): Parser;
  injectRoot(node: MarkdownNode, nodeType: NodeType, attrs?: Attrs): ParserState;
  openNode(nodeType: NodeType, attrs?: Attrs): ParserState;
  closeNode(): ParserState;
  addNode(nodeType: NodeType, attrs?: Attrs, content?: Node[]): ParserState;
  openMark(markType: MarkType, attrs?: Attrs): ParserState;
  closeMark(markType: MarkType): ParserState;
  addText(text: string): ParserState;
  next(nodes: MarkdownNode | MarkdownNode[]): ParserState;
  toDoc(): Node;
  run(remark: RemarkParser, markdown: string): ParserState;
}

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

Parser System

Serializer System

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

class SerializerState extends Stack<MarkdownNode, SerializerStackElement> {
  static create(schema: Schema, remark: RemarkParser): Serializer;
  openNode(type: string, value?: string, props?: JSONRecord): SerializerState;
  closeNode(): SerializerState;
  addNode(type: string, children?: MarkdownNode[], value?: string, props?: JSONRecord): SerializerState;
  withMark(mark: Mark, type: string, value?: string, props?: JSONRecord): SerializerState;
  closeMark(mark: Mark): SerializerState;
  next(nodes: Node | Fragment): SerializerState;
  toString(remark: RemarkParser): string;
  run(tree: Node): SerializerState;
}

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

Serializer System

Specification System

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

interface NodeParserSpec {
  match: (node: MarkdownNode) => boolean;
  runner: (state: ParserState, node: MarkdownNode, proseType: NodeType) => void;
}

interface MarkParserSpec {
  match: (node: MarkdownNode) => boolean;
  runner: (state: ParserState, node: MarkdownNode, proseType: MarkType) => void;
}

interface NodeSerializerSpec {
  match: (node: Node) => boolean;
  runner: (state: SerializerState, node: Node) => void;
}

interface MarkSerializerSpec {
  match: (mark: Mark) => boolean;
  runner: (state: SerializerState, mark: Mark, node: Node) => void | boolean;
}

Specification System

Utility System

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

class Stack<Node, Element extends StackElement<Node>> {
  size(): number;
  top(): Element | undefined;
  push(node: Node): void;
  open(node: Element): void;
  close(): Element;
}

abstract class StackElement<Node> {
  abstract push(node: Node, ...rest: Node[]): void;
}

type RemarkParser = ReturnType<typeof remark>;
type MarkdownNode = Node & { children?: MarkdownNode[] };

Utility System

Types

interface NodeSchema extends NodeSpec {
  readonly toMarkdown: NodeSerializerSpec;
  readonly parseMarkdown: NodeParserSpec;
  readonly priority?: number;
}

interface MarkSchema extends MarkSpec {
  readonly toMarkdown: MarkSerializerSpec;
  readonly parseMarkdown: MarkParserSpec;
}

interface RemarkPlugin<T = Record<string, unknown>> {
  plugin: Plugin<[T], Root>;
  options: T;
}

type JSONRecord = Record<string, JSONValue>;
type JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };