notion-any-converter-to-markdown

Custom n8n node for converting Notion blocks, comments, and database properties to Markdown

Package Information

Downloads: 1 weeklyย /ย 12 monthly
Latest Version: 1.0.1
Author: varankevich

Documentation

any-notion-block-n8n-markdow-converter-node

A powerful custom n8n node for converting Notion blocks, comments, and database properties to Markdown format with deep nesting support and multiple output formats.

๐Ÿš€ Features

Core Conversion Types

  • Comment Conversion: Convert Notion comment rich text to Markdown with full formatting support
  • Database Properties: Convert rich text database properties to Markdown with automatic property labeling
  • Page Blocks: Convert Notion page blocks with unlimited nesting depth using notion-to-md engine

Output Formats

  • Standard Markdown: Clean, compatible markdown output
  • GitHub Flavored Markdown (GFM): Enhanced with GFM-specific features like task lists and tables
  • MDX: Markdown with JSX support for React applications

Advanced Features

  • Colored Text Handling: Configurable conversion of Notion's colored text backgrounds
    • Ignore (default)
    • Convert to underline
    • Convert to bold
    • Convert to underline + bold
  • Deep Nesting Support: Handle unlimited nesting depth with optional depth limiting
  • Rich Text Processing: Full support for bold, italic, strikethrough, underline, code, and links
  • Performance Optimized: Efficient processing with metadata tracking

๐Ÿ“ฆ Installation

npm install any-notion-block-n8n-markdow-converter-node

๐Ÿ”ง Usage

  1. Add the "Notion to Markdown" node to your n8n workflow
  2. Configure the input type (comment, database_property, or page_blocks)
  3. Set the input data property containing your Notion content
  4. Choose output format (Markdown, GFM, MDX, or HTML)
  5. Configure colored text handling options
  6. Run the workflow to convert Notion content to Markdown

โš ๏ธ Important Configuration Notes

Input Data Property Field:

  • Enter the property name that contains your data (e.g., "data", "json", "body")
  • DO NOT enter expressions like {{ $json.rich_text }} in this field
  • The node will automatically handle the data extraction from the specified property

Correct Examples:

  • โœ… data (if your data is in items[0].json.data)
  • โœ… json (if your data is in items[0].json.json)
  • โœ… body (if your data is in items[0].json.body)

Incorrect Examples:

  • โŒ {{ $json.rich_text }} (this is an expression, not a property name)
  • โŒ $json.data (this is an expression, not a property name)

Special Case: If you need to pass data directly via expressions, the node will automatically detect this and handle it appropriately.

๐Ÿ“‹ Input Types & Examples

1. Comment Conversion

Process Notion comment objects with rich text formatting:

Input:

{
  "rich_text": [
    {
      "type": "text",
      "text": {"content": "This is "},
      "annotations": {"bold": false, "italic": false, "color": "default"}
    },
    {
      "type": "text",
      "text": {"content": "formatted text"},
      "annotations": {"bold": true, "italic": true, "color": "red_background"}
    }
  ]
}

Output (with underline colored text):

This is <u>***formatted text***</u>

2. Database Property Conversion

Convert database property fields with automatic labeling:

Input:

{
  "properties": {
    "Title": {
      "type": "title",
      "title": [{"type": "text", "text": {"content": "Task Title"}}]
    },
    "Description": {
      "type": "rich_text", 
      "rich_text": [{"type": "text", "text": {"content": "Task description"}}]
    }
  }
}

Output:

# Task Title

**Description:** Task description

3. Page Blocks Conversion

Process full Notion page content with nested structures:

Input:

{
  "blocks": [
    {
      "type": "heading_1",
      "heading_1": {
        "rich_text": [{"type": "text", "text": {"content": "Main Section"}}]
      }
    },
    {
      "type": "paragraph",
      "paragraph": {
        "rich_text": [{"type": "text", "text": {"content": "Content paragraph"}}]
      }
    }
  ]
}

Output:

# Main Section

Content paragraph

โš™๏ธ Configuration Options

Input Type

  • comment - Single Notion comment processing
  • database_property - Database field conversion
  • page_blocks - Full page content with nesting

Output Format

  • markdown - Standard Markdown
  • gfm - GitHub Flavored Markdown
  • mdx - MDX (Markdown + JSX)
  • html - Semantic HTML markup

Colored Text Handling

  • ignore - Skip colored backgrounds (default)
  • underline - Convert to <u> tags
  • bold - Convert to **bold**
  • underline_bold - Combine both treatments

Advanced Options

  • maxDepth - Limit nesting depth for page blocks (0 = unlimited)
  • inputProperty - Source property name (default: "data")
  • outputProperty - Target property name (default: "markdown")

๐Ÿงช Testing & Development

# Install dependencies
npm install

# Run tests
npm test

# Build the node
npm run build

# Run linting
npm run lint

# Development with auto-rebuild
npm run dev

Test Coverage

  • โœ… Comment conversion with all formatting options
  • โœ… Database property handling (single and multiple)
  • โœ… Page blocks with notion-to-md integration
  • โœ… All output formats (Markdown, GFM, MDX, HTML)
  • โœ… Colored text handling variations
  • โœ… Error handling and edge cases
  • โœ… Performance benchmarks (1000+ elements, 70KB+ content)
  • โœ… Edge case testing (15+ malformed data scenarios)
  • โœ… Concurrent processing and memory leak testing
  • โœ… Real-world data validation

๐Ÿ“Š Sample Outputs

See SAMPLE_OUTPUT.md for detailed examples of conversion results with your actual comment data.

๐Ÿ—๏ธ Architecture

โ”œโ”€โ”€ nodes/NotionToMarkdown/    # Main n8n node implementation
โ”œโ”€โ”€ conversion/               # Conversion logic by input type
โ”‚   โ”œโ”€โ”€ comments.ts          # Comment processing
โ”‚   โ”œโ”€โ”€ databaseProperties.ts # Database field processing  
โ”‚   โ””โ”€โ”€ pageBlocks.ts        # Page content processing
โ”œโ”€โ”€ utils/                   # Shared utilities
โ”‚   โ”œโ”€โ”€ richTextFormatter.ts # Rich text to markdown conversion
โ”‚   โ””โ”€โ”€ formatConverter.ts   # Output format conversion
โ””โ”€โ”€ types/                   # TypeScript definitions

๐Ÿค Contributing

This node is built for defensive security use only. Contributions should focus on:

  • Improving conversion accuracy
  • Adding support for new Notion block types
  • Performance optimizations
  • Documentation enhancements

๐Ÿ™ Attribution

This project incorporates and builds upon excellent open source work:

Special thanks to the n8n community and Notion's public API documentation.

โš–๏ธ Licensing & Legal

License

MIT License - see LICENSE file for complete terms.

Intellectual Property

  • Original Implementation: All conversion logic, UI, validation, and advanced features are original implementations
  • Dependencies: Uses only MIT-licensed and permissive open source dependencies
  • Commercial Use: Fully permitted for commercial and enterprise use
  • Patent Safety: No known patent conflicts for markdown conversion functionality

Compliance

This project complies with all applicable licenses and follows best practices for open source development. See LICENSING_ANALYSIS.md for detailed IP analysis.

Package Naming Note

โš ๏ธ Important: Consider renaming from "any-notion-block-n8n-markdow-converter-node" to "n8n-blocks-markdown-converter" to avoid potential trademark concerns with the "Notion" trademark.

๐Ÿ› Troubleshooting

Common Issues

Error: inputProperty.trim is not a function

  • Cause: You entered an expression (like {{ $json.rich_text }}) in the "Input Data Property" field instead of a property name
  • Solution: Enter the property name only (e.g., "data", "json", "body")
  • Fixed in: Version 1.0.1+

Error: No data found in property 'X'

  • Cause: The specified property doesn't exist in your input data
  • Solution: Check available properties in your input data and update the property name

Error: Invalid comment data: Comment input must contain a "rich_text" array

  • Cause: Your input data doesn't match the expected structure for the selected input type
  • Solution: Verify your input type matches your data structure, or use the correct input type

๐Ÿ“„ License

MIT License - see LICENSE file for details

Discussion