HAST to MDAST Transformer Utility
hast-util-to-mdast is a core utility within the unified.js ecosystem designed to transform a HAST (HTML Abstract Syntax Tree) into an MDAST (Markdown Abstract Syntax Tree). This package is essential for converting HTML content into Markdown programmatically, often serving as the engine behind higher-level plugins like `rehype-remark`. The current stable version is 10.1.2. The package maintains an active release cadence, with frequent patch and minor updates addressing bug fixes and feature enhancements, alongside major versions that typically align with Node.js LTS updates or significant API refinements. Key differentiators include its tight integration with the unified ecosystem, robust handling of various HTML structures, and the provision of a flexible API with custom handlers for fine-grained control over the transformation process, allowing developers to define how specific HTML elements or nodes should be represented in Markdown.
Common errors
-
TypeError: require is not a function in ES module scope
cause Attempting to use `require()` to import `hast-util-to-mdast` in a project configured for ESM, or after upgrading to v10+ in a CommonJS project.fixChange `const { toMdast } = require('hast-util-to-mdast');` to `import { toMdast } from 'hast-util-to-mdast';`. Ensure your project's `package.json` includes `"type": "module"` or uses `.mjs` files for ESM. -
TypeError: Cannot read properties of undefined (reading 'one') or (reading 'all')
cause You've upgraded from a version prior to 9.0.0 to 9.0.0 or later and are still trying to import or use `one` or `all` functions directly.fixThese functions are no longer direct exports. When implementing custom handlers, access them via the `state` object passed to your handler: `state.one(node, parent)` and `state.all(node, parent)`. -
Error: This package now requires Node.js 16. Please upgrade your Node.js version.
cause Running `hast-util-to-mdast` version 10.0.0 or higher on an unsupported Node.js version (e.g., Node.js 14).fixUpgrade your Node.js runtime environment to version 16 or newer. Use `nvm install 16` (or higher) and `nvm use 16` if using Node Version Manager.
Warnings
- breaking Version 10.0.0 introduced a breaking change requiring Node.js 16 or later. Previous versions (9.x) supported Node.js 14.14+ or later, and earlier versions supported Node.js 12+.
- breaking Since version 10.0.0, this package is ESM-only (ECMAScript Modules). The 'exports' field was added to `package.json`, making CommonJS `require()` incompatible.
- breaking Version 9.0.0 significantly changed the API for custom handlers. The `h` parameter was replaced with a more powerful `state` object, and the `one` and `all` exports were removed in favor of `state.one` and `state.all`.
- gotcha Prior to version 10.1.2, `br` (line break) elements within phrasing content could be unexpectedly dropped during the transformation process, leading to a loss of intended layout.
Install
-
npm install hast-util-to-mdast -
yarn add hast-util-to-mdast -
pnpm add hast-util-to-mdast
Imports
- toMdast
const toMdast = require('hast-util-to-mdast')import { toMdast } from 'hast-util-to-mdast' - defaultHandlers
import { defaultHandlers } from 'hast-util-to-mdast' - State
import type { State } from 'hast-util-to-mdast'
Quickstart
import fs from 'node:fs/promises';
import { fromHtml } from 'hast-util-from-html';
import { toMdast } from 'hast-util-to-mdast';
import { toMarkdown } from 'mdast-util-to-markdown';
async function convertHtmlToMarkdown(htmlString: string): Promise<string> {
// Parse the HTML string into a HAST (HTML Abstract Syntax Tree) fragment.
const hast = fromHtml(htmlString, { fragment: true });
// Transform the HAST tree into an MDAST (Markdown Abstract Syntax Tree).
const mdast = toMdast(hast);
// Serialize the MDAST tree back into a Markdown string.
const markdown = toMarkdown(mdast);
return markdown;
}
// Example usage:
const exampleHtml = '<h2>Hello <strong>world!</strong></h2><p>This is a paragraph with a <a href="#">link</a> and a <br>line break.</p>';
convertHtmlToMarkdown(exampleHtml)
.then(markdown => {
console.log('Original HTML:\n', exampleHtml);
console.log('\nConverted Markdown:\n', markdown);
})
.catch(error => {
console.error('Conversion failed:', error);
});
// To show an actual file read (requires 'example.html' file):
// const htmlFilePath = './example.html';
// try {
// const fileHtml = await fs.readFile(htmlFilePath, 'utf8');
// const convertedFileMarkdown = await convertHtmlToMarkdown(fileHtml);
// console.log(`\nMarkdown from ${htmlFilePath}:\n`, convertedFileMarkdown);
// } catch (err) {
// console.error(`Could not read file ${htmlFilePath}:`, err);
// }