@m2d/remark-docx
TypeScript icon, indicating that this package has built-in type declarations

0.1.0 • Public • Published

@m2d/remark-docx

test codecov Version Downloads Bundle Size

A Unified/Remark plugin that injects a DOCX compiler using mdast2docx and outputs .docx files from Markdown.


🧭 Overview

@m2d/remark-docx enables direct export of Markdown content to Microsoft Word (.docx) using the Unified ecosystem. It seamlessly bridges remark with the mdast2docx compiler and auto-injects common plugins like GFM tables, math, lists, and inline HTML support.

It’s designed for both browser and Node.js environments, handling environment-specific features like image or HTML parsing smartly.


✨ Features

  • 📄 Converts Markdown to .docx using mdast2docx
  • 🔌 Auto-injects plugins for GFM tables, math, lists, images, and HTML
  • 🧠 Smart: excludes DOM-only plugins in Node.js
  • 💥 Supports both .process() and .processSync() with an async .result
  • 🔄 Output as Blob, Buffer, or base64

📦 Installation

npm install @m2d/remark-docx docx

Also install any optional plugins you wish to include in your pipeline:

npm install remark-parse remark-gfm remark-math remark-frontmatter

Other package managers:

yarn add @m2d/remark-docx docx
pnpm add @m2d/remark-docx docx

🚀 Usage

🔗 Browser Example (Async)

import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkGfm from "remark-gfm";
import remarkMath from "remark-math";
import remarkFrontmatter from "remark-frontmatter";
import { remarkDocx } from "@m2d/remark-docx";

const processor = unified()
  .use(remarkParse)
  .use(remarkGfm)
  .use(remarkFrontmatter)
  .use(remarkMath)
  .use(remarkDocx);

const downloadDocx = () => {
  processor
    .process(md)
    .then(res => res.result)
    .then(blob => {
      const url = URL.createObjectURL(blob as Blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = "document.docx";
      link.click();
      URL.revokeObjectURL(url);
    });
};

⚡ Browser Example (Sync + Async Result)

const { result } = processor.processSync(md) as { result: Promise<Blob> };
result.then(blob => {
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = "document.docx";
  link.click();
  URL.revokeObjectURL(url);
});

🐢 Node.js Example

import fs from "node:fs";
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkGfm from "remark-gfm";
import remarkMath from "remark-math";
import remarkFrontmatter from "remark-frontmatter";
import { remarkDocx } from "@m2d/remark-docx";

const markdown = `
# Hello DOCX

This is a *Markdown* document with **tables**, math, and more.

| A | B |
|---|---|
| 1 | 2 |

Inline math: $x^2 + y^2 = z^2$
`;

const processor = unified()
  .use(remarkParse)
  .use(remarkGfm)
  .use(remarkFrontmatter)
  .use(remarkMath)
  .use(remarkDocx, "buffer"); // outputType = "buffer" in Node

const { result } = processor.processSync(markdown) as { result: Promise<Buffer> };

result.then(buffer => {
  fs.writeFileSync("output.docx", buffer);
  console.log("✔ DOCX file written: output.docx");
});

🧩 Plugin Behavior

By default, these mdast2docx plugins are included:

Plugin Description
htmlPlugin Parses inline HTML
tablePlugin GFM table support
listPlugin Ordered/unordered lists
mathPlugin KaTeX math blocks
imagePlugin Resolves images

On Node.js, htmlPlugin and imagePlugin are automatically excluded to avoid DOM dependency issues.

To override this behavior, pass custom plugins using sectionProps.plugins.


📘 API

remarkDocx(outputType?, docxProps?, sectionProps?)

Param Type Description
outputType "blob" | "buffer" | "base64" Default is "blob"
docxProps IDocxProps Global DOCX config (optional)
sectionProps ISectionProps Section + plugin control (optional)

Returns a Processor where .result on vfile is a Promise<Blob | Buffer | string> depending on the mode.


🔥 Output Handling

Both .process() and .processSync() return a vfile with a result field:

const file = await processor.process(md);
const blobOrBuffer = await file.result;

This makes the plugin environment-safe and decoupled from internal mutation or I/O.


🛠 Development

npm run dev       # Watch mode
npm run build     # Compile to /dist
npm run lint      # Lint source
npm run test      # Run tests

📄 License

Licensed under the MPL-2.0 License.


💖 Sponsors

Support the project & its ecosystem:


🔗 Related Projects


Made with 💖 by Mayank Kumar Chaudhari

Package Sidebar

Install

npm i @m2d/remark-docx

Weekly Downloads

1,965

Version

0.1.0

License

MPL-2.0

Unpacked Size

11.1 kB

Total Files

5

Last publish

Collaborators

  • mayank1513