Skip to main content

Overview

The Markdown Encoder converts AppFlowy Editor Document objects into Markdown strings. It provides a flexible parser-based system that supports various document elements including headings, lists, tables, quotes, and more.

DocumentMarkdownEncoder

The main class for encoding documents to Markdown format.

Constructor

DocumentMarkdownEncoder({
  List<NodeParser> parsers = const [],
  String lineBreak = '',
})

Parameters

  • parsers (List<NodeParser>): List of node parsers that define how each node type is converted to Markdown. Default is an empty list.
  • lineBreak (String): Optional line break string to insert between nodes. Default is empty.

Methods

convert

String convert(Document input)
Converts a complete Document to a Markdown string. Parameters:
  • input (Document): The document to convert
Returns: String - The Markdown representation of the document Example:
final document = Document.fromJson(data);
final encoder = DocumentMarkdownEncoder(
  parsers: [
    const TextNodeParser(),
    const HeadingNodeParser(),
    const BulletedListNodeParser(),
    const NumberedListNodeParser(),
    const TodoListNodeParser(),
    const QuoteNodeParser(),
    const CodeBlockNodeParser(),
    const ImageNodeParser(),
    const TableNodeParser(),
  ],
);
final markdown = encoder.convert(document);

convertNodes

String convertNodes(
  List<Node> nodes, {
  bool withIndent = false,
})
Converts a list of nodes to Markdown format. Parameters:
  • nodes (List<Node>): List of nodes to convert
  • withIndent (bool): If true, indents each line with a tab character
Returns: String - The Markdown representation

Helper Function

documentToMarkdown

A convenient helper function that provides a simpler API with default parsers.
String documentToMarkdown(
  Document document, {
  List<NodeParser> customParsers = const [],
  String lineBreak = '',
})
Parameters:
  • document (Document): The document to convert
  • customParsers (List<NodeParser>): Additional custom parsers to use
  • lineBreak (String): Optional line break string between nodes
Returns: String - The Markdown string Example:
import 'package:appflowy_editor/appflowy_editor.dart';

// Simple usage with default parsers
final markdown = documentToMarkdown(document);

// With custom parsers
final markdown = documentToMarkdown(
  document,
  customParsers: [MyCustomParser()],
  lineBreak: '\n',
);

Supported Node Types

The default implementation includes parsers for:
  • Text/Paragraphs: Plain text with inline formatting (bold, italic, code, etc.)
  • Headings: H1-H6 heading levels
  • Bulleted Lists: Unordered lists with * or -
  • Numbered Lists: Ordered lists with numbers
  • Todo Lists: Checkboxes with [x] or [ ]
  • Quotes: Block quotes with >
  • Code Blocks: Fenced code blocks with triple backticks
  • Images: Image syntax ![alt](url)
  • Tables: Markdown table format with pipes
  • Dividers: Horizontal rules

Example Output

final document = Document.fromJson({
  'type': 'page',
  'children': [
    {
      'type': 'heading',
      'data': {
        'level': 2,
        'delta': [
          {'insert': 'Welcome to '},
          {'insert': 'AppFlowy Editor', 'attributes': {'bold': true}}
        ]
      }
    },
    {
      'type': 'paragraph',
      'data': {
        'delta': [
          {'insert': 'A '},
          {'insert': 'customizable', 'attributes': {'bold': true}},
          {'insert': ' editor'}
        ]
      }
    },
    {
      'type': 'bulleted_list',
      'data': {
        'delta': [{'insert': 'Feature one'}]
      }
    },
    {
      'type': 'bulleted_list',
      'data': {
        'delta': [{'insert': 'Feature two'}]
      }
    }
  ]
});

final markdown = documentToMarkdown(document);
// Output:
// ## Welcome to **AppFlowy Editor**
//
// A **customizable** editor
// * Feature one
// * Feature two

Custom Parsers

You can create custom parsers by implementing the NodeParser interface:
class CustomNodeParser extends NodeParser {
  const CustomNodeParser();

  @override
  String get id => 'custom_node_type';

  @override
  String transform(Node node, DocumentMarkdownEncoder encoder) {
    // Custom transformation logic
    return '...';
  }
}

// Use your custom parser
final markdown = documentToMarkdown(
  document,
  customParsers: [const CustomNodeParser()],
);

See Also

Build docs developers (and LLMs) love