@jinzhongjia/markdown-docx
v1.0.4
Published
A powerful TypeScript library that converts Markdown files to DOCX format with high fidelity
Maintainers
Readme
markdown-docx
A powerful TypeScript library that converts Markdown files to DOCX format with high fidelity, supporting both browser and Node.js environments.
功能强大的 TypeScript 库,高保真地将 Markdown 文件转换为 DOCX 格式,支持浏览器和 Node.js 环境。
Online Demo
What is markdown-docx?
markdown-docx is a comprehensive solution for converting Markdown documents into Microsoft Word DOCX format while preserving formatting, structure, and styling. Built with TypeScript, it offers both programmatic APIs and command-line tools for seamless integration into any workflow.
Key Capabilities
- High-Fidelity Conversion: Maintains document structure, formatting, and styling
- Universal Compatibility: Works seamlessly in browsers and Node.js environments
- Rich Content Support: Handles images, tables, code blocks, lists, links, and footnotes
- Syntax Highlighting: Advanced code syntax highlighting with 200+ language support
- Customizable Styling: Full control over document appearance and formatting
- Image Processing: Automatic image downloading and format conversion
- TypeScript Support: Full type safety and IntelliSense support
Features

- 📝 High-Fidelity Conversion: Convert Markdown to DOCX with precise formatting preservation
- 🎨 Syntax Highlighting: Advanced code block highlighting with 200+ programming languages
- 🖼️ Smart Image Handling: Automatic image downloading, resizing, and format conversion (including WebP)
- 📋 Rich Content Support: Tables, lists, blockquotes, headings, and task lists
- 🔗 Advanced Linking: Hyperlinks, footnotes, and reference-style links
- 💅 Customizable Styling: Complete control over fonts, colors, spacing, and layout
- 🌐 Cross-Platform: Works in browsers, Node.js, and as a CLI tool
- 🖥️ Command-Line Interface: Easy-to-use CLI for batch processing and automation
- ⚡ Performance Optimized: Efficient processing with lazy loading and caching
- 🔧 Extensible: Plugin system for custom renderers and extensions
Installation
# Using npm
npm install @jinzhongjia/markdown-docx
# Using yarn
yarn add @jinzhongjia/markdown-docx
# Using pnpm
pnpm add @jinzhongjia/markdown-docxBasic Usage
Node.js
import fs from 'node:fs/promises';
import markdownDocx, { Packer } from 'markdown-docx';
async function convertMarkdownToDocx() {
// Read markdown content
const markdown = await fs.readFile('input.md', 'utf-8');
// Convert to docx
const doc = await markdownDocx(markdown);
// Save to file
const buffer = await Packer.toBuffer(doc);
await fs.writeFile('output.docx', buffer);
console.log('Conversion completed successfully!');
}
convertMarkdownToDocx();Browser
import markdownDocx, { Packer } from '@jinzhongjia/markdown-docx';
async function convertMarkdownToDocx(markdownText) {
// Convert to docx
const doc = await markdownDocx(markdownText);
// Generate blob for download
const blob = await Packer.toBlob(doc);
// Create download link
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'document.docx';
a.click();
// Clean up
URL.revokeObjectURL(url);
}
// Example usage with a textarea
document.getElementById('convert-btn').addEventListener('click', () => {
const markdown = document.getElementById('markdown-input').value;
convertMarkdownToDocx(markdown);
});Advanced Usage
Using the MarkdownDocx Class
For more control over the conversion process, you can use the MarkdownDocx class directly:
import { MarkdownDocx, Packer } from '@jinzhongjia/markdown-docx';
import fs from 'node:fs/promises';
async function convertWithOptions() {
const markdown = await fs.readFile('input.md', 'utf-8');
// Create instance with options
const converter = new MarkdownDocx(markdown)
// Generate document
const doc = await converter.toDocument({
title: 'My Document',
creator: 'markdown-docx',
description: 'Generated from Markdown'
});
// Save to file
const buffer = await Packer.toBuffer(doc);
await fs.writeFile('output.docx', buffer);
}API Reference
Main Functions
markdownDocx(markdown, options?)
The primary function to convert Markdown to DOCX.
import markdownDocx, { Packer } from '@jinzhongjia/markdown-docx'
const doc = await markdownDocx(markdown, options)
const buffer = await Packer.toBuffer(doc)Parameters:
markdown(string): The Markdown content to convertoptions(MarkdownDocxOptions, optional): Configuration options
Returns: Promise<Document> - A DOCX document object
MarkdownDocx.covert(markdown, options?)
Static method equivalent to the main function.
import { MarkdownDocx } from '@jinzhongjia/markdown-docx'
const doc = await MarkdownDocx.covert(markdown, options)MarkdownDocx Class
Constructor
import { MarkdownDocx } from '@jinzhongjia/markdown-docx'
const converter = new MarkdownDocx(markdown, options)Methods
toDocument(documentOptions?)
Converts the Markdown to a DOCX document.
const doc = await converter.toDocument({
title: 'My Document',
creator: 'Your Name',
description: 'Document description',
subject: 'Document subject'
})Parameters:
documentOptions(IPropertiesOptions, optional): Document metadata and properties
toSection()
Converts Markdown to document sections (advanced usage).
const sections = await converter.toSection()Configuration Options
MarkdownDocxOptions
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| imageAdapter | MarkdownImageAdapter | Built-in adapter | Custom function to handle image processing |
| ignoreImage | boolean | false | Skip image processing and rendering |
| ignoreFootnote | boolean | false | Skip footnote processing and rendering |
| ignoreHtml | boolean | false | Skip inline HTML processing |
| gfm | boolean | true | Enable GitHub Flavored Markdown support |
| document | IPropertiesOptions | {} | Document metadata and properties |
| codeHighlight | CodeHighlightOptions | {} | Code syntax highlighting configuration |
| imageSize | ImageSizeOptions | {} | Image sizing and scaling configuration |
CodeHighlightOptions
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| enabled | boolean | true | Enable/disable syntax highlighting |
| theme | BundledTheme | 'github-light' | Syntax highlighting theme |
| languages | BundledLanguage[] | Common languages | Supported programming languages |
| showLineNumbers | boolean | false | Display line numbers in code blocks |
| showLanguage | boolean | false | Display language label above code blocks |
| autoDetect | boolean | true | Automatically detect programming language |
| defaultLanguage | string | 'plaintext' | Fallback language for unspecified code blocks |
ImageSizeOptions
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| maxWidth | number | 600 | Maximum width for images in pixels |
| maxHeight | number | 400 | Maximum height for images in pixels |
| minWidth | number | 50 | Minimum width for very small images |
| minHeight | number | 50 | Minimum height for very small images |
Document Properties (IPropertiesOptions)
| Option | Type | Description |
|--------|------|-------------|
| title | string | Document title |
| creator | string | Document author |
| description | string | Document description |
| subject | string | Document subject |
| keywords | string | Document keywords |
| lastModifiedBy | string | Last modified by |
| company | string | Company name |
Additional options from the marked library are also supported.
Command Line Interface
markdown-docx includes a CLI tool for converting markdown files from the command line:
# Install globally
npm install -g @jinzhongjia/markdown-docx
# Basic usage
markdown-docx --input input.md --output output.docx
# Short form
markdown-docx -i input.md -o output.docxIf the output file is not specified, it will use the input filename with a .docx extension.
Development & Release
Development Scripts
# Development mode with hot reload
pnpm run dev
# Build the project
pnpm run build
# Run tests (single run)
pnpm run test
# Run tests in watch mode
pnpm run test:watch
# Run tests with coverage
pnpm run test:coverage
# Convert markdown to DOCX (development)
pnpm convert -i input.md -o output.docxRelease Management
This project uses release-it for automated releases:
# Test release process (dry-run)
pnpm run release:dry
# Release with automatic version increment
pnpm run release
# Release specific version types
pnpm run release:patch # 1.0.0 -> 1.0.1
pnpm run release:minor # 1.0.0 -> 1.1.0
pnpm run release:major # 1.0.0 -> 2.0.0The release process automatically:
- Runs tests before release
- Builds the project
- Updates version in package.json
- Creates git tag and commit
- Publishes to npm
- Creates GitHub release with changelog
Supported Markdown Features
- Headings (H1-H6)
- Paragraphs and line breaks
- Emphasis (bold, italic, strikethrough)
- Lists (ordered and unordered)
- Links and images
- Blockquotes
- Code blocks
- Tables
- Horizontal rules
- Footnotes
- Task lists (checkboxes)
Advanced Usage Examples
Code Syntax Highlighting
Enable advanced syntax highlighting with custom themes and options:
import markdownDocx, { Packer } from '@jinzhongjia/markdown-docx'
const doc = await markdownDocx(markdown, {
codeHighlight: {
enabled: true,
theme: 'github-dark',
showLineNumbers: true,
showLanguage: true,
languages: ['javascript', 'typescript', 'python', 'java'],
defaultLanguage: 'javascript'
}
})
const buffer = await Packer.toBuffer(doc)Custom Document Properties
Set document metadata and properties:
import { MarkdownDocx, Packer } from '@jinzhongjia/markdown-docx'
const converter = new MarkdownDocx(markdown, {
document: {
title: 'Technical Documentation',
creator: 'Development Team',
description: 'API Reference Guide',
subject: 'Software Documentation',
keywords: 'API, REST, Documentation',
company: 'Your Company'
}
})
const doc = await converter.toDocument({
title: 'Override Title', // This will override the document.title above
})Ignoring Specific Elements
Skip processing certain Markdown elements:
const doc = await markdownDocx(markdown, {
ignoreImage: true, // Skip all images
ignoreFootnote: true, // Skip footnotes
ignoreHtml: true, // Skip inline HTML
gfm: false // Disable GitHub Flavored Markdown
})Custom Image Sizing
Control image dimensions in the generated DOCX:
const doc = await markdownDocx(markdown, {
imageSize: {
maxWidth: 800, // Larger images will be scaled down
maxHeight: 600, // Maintain aspect ratio
minWidth: 100, // Very small images will be scaled up
minHeight: 80 // Ensure readability
}
})Custom Image Adapter
Create a custom image adapter for specialized image processing:
import { MarkdownImageAdapter, MarkdownImageItem } from '@jinzhongjia/markdown-docx'
const customImageAdapter: MarkdownImageAdapter = async (token) => {
// Custom image processing logic
const response = await fetch(token.href)
const buffer = await response.arrayBuffer()
// Process image, resize, convert format, etc.
const processedImage = await processImage(buffer)
return {
type: 'png',
data: processedImage,
width: 800,
height: 600
}
}
const doc = await markdownDocx(markdown, {
imageAdapter: customImageAdapter
})Batch Processing Multiple Files
Process multiple Markdown files in Node.js:
import fs from 'node:fs/promises'
import path from 'node:path'
import markdownDocx, { Packer } from 'markdown-docx'
async function batchConvert(inputDir, outputDir) {
const files = await fs.readdir(inputDir)
const markdownFiles = files.filter(file => file.endsWith('.md'))
for (const file of markdownFiles) {
const markdown = await fs.readFile(path.join(inputDir, file), 'utf-8')
const doc = await markdownDocx(markdown, {
codeHighlight: { enabled: true, theme: 'github-light' }
})
const buffer = await Packer.toBuffer(doc)
const outputFile = path.join(outputDir, file.replace('.md', '.docx'))
await fs.writeFile(outputFile, buffer)
console.log(`Converted ${file} -> ${path.basename(outputFile)}`)
}
}
await batchConvert('./docs', './output')Image Adapter Interface
The library provides built-in image adapters for both browser and Node.js environments. You can create custom adapters by implementing the MarkdownImageAdapter interface:
type MarkdownImageAdapter = (token: Tokens.Image) => Promise<null | MarkdownImageItem>
interface MarkdownImageItem {
type: 'jpg' | 'png' | 'gif' | 'bmp'
data: Buffer | string | Uint8Array | ArrayBuffer
width: number
height: number
}Built-in Features
- Automatic downloading of images from URLs
- Format conversion (WebP to PNG in browsers)
- Size detection and optimization
- Caching to avoid duplicate downloads
- Error handling with graceful fallbacks
Style Customization
You can customize the appearance of generated DOCX documents by modifying the built-in styles:
import { styles, colors, classes } from '@jinzhongjia/markdown-docx'
// Customize hyperlink color
styles.default.hyperlink.run.color = '0077cc'
// Customize code block styling
styles.markdown.code.run.color = '000000'
styles.markdown.code.run.font = 'Fira Code'
// Customize heading styles
styles.markdown.heading1.run.size = 40 // 20pt
styles.markdown.heading1.run.color = '2E86AB'
// Customize blockquote styling
styles.markdown.blockquote.run.italics = true
styles.markdown.blockquote.paragraph.border.left.color = 'A23B72'Available Style Objects
| Style Object | Description | File Reference |
|-------------|-------------|----------------|
| styles.default | Default document styles (hyperlinks, headings) | styles.ts |
| styles.markdown | Markdown-specific element styles | markdown.ts |
| styles.colors | Color palette definitions | colors.ts |
| styles.classes | CSS class name mappings | classes.ts |
Custom Style Properties
You can modify various style properties:
// Text formatting
styles.markdown.strong.run.bold = true
styles.markdown.em.run.italics = true
styles.markdown.del.run.strike = true
// Spacing and layout
styles.markdown.paragraph.paragraph.spacing.before = 200
styles.markdown.paragraph.paragraph.spacing.after = 200
// Borders and backgrounds
styles.markdown.code.paragraph.border.top.color = 'E1E4E8'
styles.markdown.code.paragraph.shading.fill = 'F6F8FA'
// Font and size
styles.markdown.code.run.font = 'Consolas'
styles.markdown.code.run.size = 20 // 10ptEnvironment Compatibility
The library automatically detects the runtime environment and adapts accordingly:
Browser Environment
- Image Processing: Uses Fetch API for downloading images
- WebP Support: Automatic conversion to PNG using Canvas API
- Bundle Size: Optimized browser bundle with tree-shaking
- Async Operations: Non-blocking with Web Workers support
Node.js Environment
- Image Processing: Uses built-in HTTP/HTTPS modules
- File System: Direct file system access for local images
- Performance: Optimized for server-side batch processing
- Memory Management: Efficient buffer handling for large files
Key Differences
| Feature | Browser | Node.js | |---------|---------|---------| | Image Download | Fetch API | HTTP/HTTPS modules | | WebP Support | Canvas conversion | Not supported (logs warning) | | Local Files | Not supported | Direct file access | | Bundle Size | ~2MB (minified) | Full feature set | | Performance | Limited by browser | Full system resources |
Examples
For more examples, see the tests directory in the repository.
License
This project is licensed under the MIT License - see the LICENSE file for details.
