Browse by type
[![Build][build-badge]][build] [![Coverage][coverage-badge]][coverage] [![Downloads][downloads-badge]][downloads] [![Size][size-badge]][size] [![Sponsors][sponsors-badge]][collective] [![Backers][backers-badge]][collective] [![Chat][chat-badge]][chat]
[mdast][] utility that turns a syntax tree into markdown.
toMarkdown(tree[, options])defaultHandlersConstructNameConstructNameMapHandleHandlersInfoJoinMapOptionsSafeConfigStateTrackerUnsafeThis package is a utility that takes an [mdast][] syntax tree as input and turns it into serialized markdown.
This utility is a low level project.
It’s used in [remark-stringify][remark-stringify], which focusses on making it
easier to transform content by abstracting these internals away.
If you want to handle syntax trees manually, use this. For an easier time processing content, use the [remark][] ecosystem instead.
You can combine this utility with other utilities to add syntax extensions.
Notable examples that deeply integrate with it are
[mdast-util-gfm][mdast-util-gfm],
[mdast-util-mdx][mdast-util-mdx],
[mdast-util-frontmatter][mdast-util-frontmatter],
[mdast-util-math][mdast-util-math], and
[mdast-util-directive][mdast-util-directive].
This package is [ESM only][esm]. In Node.js (version 16+), install with [npm][]:
npm install mdast-util-to-markdown
In Deno with [esm.sh][esmsh]:
import {toMarkdown} from 'https://esm.sh/mdast-util-to-markdown@2'
In browsers with [esm.sh][esmsh]:
<script type="module">
import {toMarkdown} from 'https://esm.sh/mdast-util-to-markdown@2?bundle'
</script>
Say our module example.js looks as follows:
/**
* @import {Root} from 'mdast'
*/
import {toMarkdown} from 'mdast-util-to-markdown'
/** @type {Root} */
const tree = {
type: 'root',
children: [
{
type: 'blockquote',
children: [
{type: 'thematicBreak'},
{
type: 'paragraph',
children: [
{type: 'text', value: '- a\nb !'},
{
type: 'link',
url: 'example.com',
children: [{type: 'text', value: 'd'}]
}
]
}
]
}
]
}
console.log(toMarkdown(tree))
…now running node example.js yields:
> ***
>
> \- a
> b \
👉 Note: observe the properly escaped characters which would otherwise turn into a list and image respectively.
This package exports the identifiers [defaultHandlers][api-default-handlers]
and [toMarkdown][api-to-markdown].
There is no default export.
toMarkdown(tree[, options])Turn an [mdast][] syntax tree into markdown.
tree ([Node][node])
— tree to serializeoptions ([Options][api-options], optional)
— configurationSerialized markdown representing tree (string).
defaultHandlersDefault (CommonMark) handlers ([Handlers][api-handlers]).
ConstructNameConstruct names for things generated by mdast-util-to-markdown (TypeScript
type).
This is an enum of strings, each being a semantic label, useful to know when
serializing whether we’re for example in a double (") or single (') quoted
title.
type ConstructName = ConstructNameMap[keyof ConstructNameMap]
ConstructNameMapInterface of registered constructs (TypeScript type).
interface ConstructNameMap { /* see code */ }
When working on extensions that use new constructs, extend the corresponding interface to register its name:
declare module 'mdast-util-to-markdown' {
interface ConstructNameMap {
// Register a new construct name (value is used, key should match it).
gfmStrikethrough: 'gfmStrikethrough'
}
}
HandleHandle a particular node (TypeScript type).
node (any)
— expected mdast nodeparent ([Node][node], optional)
— parent of nodestate ([State][api-state])
— info passed around about the current stateinfo ([Info][api-info])
— info on the surrounding of the node that is serializedSerialized markdown representing node (string).
HandlersHandle particular nodes (TypeScript type).
Each key is a node type (Node['type']), each value its corresponding handler
([Handle][api-handle]).
type Handlers = Record<Node['type'], Handle>
InfoInfo on the surrounding of the node that is serialized (TypeScript type).
now ([Point][point])
— current pointlineShift (number)
— number of columns each line will be shifted by wrapping nodesbefore (string)
— characters before this (guaranteed to be one, can be more)after (string)
— characters after this (guaranteed to be one, can be more)JoinHow to join two blocks (TypeScript type).
“Blocks” are typically joined by one blank line. Sometimes it’s nicer to have them flush next to each other, yet other times they cannot occur together at all.
Join functions receive two adjacent siblings and their parent and what they return defines how many blank lines to use between them.
left ([Node][node])
— first of two adjacent siblingsright ([Node][node])
— second of two adjacent siblingsparent ([Node][node])
— parent of the two siblingsstate ([State][api-state])
— info passed around about the current stateHow many blank lines to use between the siblings (boolean, number,
optional).
Where true is as passing 1 and false means the nodes cannot be
joined by a blank line, such as two adjacent block quotes or indented code
after a list, in which case a comment will be injected to break them up:
> Quote 1
> Quote 2
👉 Note: abusing this feature will break markdown. One such example is when returning
0for two paragraphs, which will result in the text running together, and in the future to be seen as one paragraph.
MapMap function to pad a single line (TypeScript type).
value (string)
— a single line of serialized markdownline (number)
— line number relative to the fragmentblank (boolean)
— whether the line is considered blank in markdownPadded line (string).
OptionsConfiguration (TypeScript type).
The following fields influence how markdown is serialized.
options.bulletMarker to use for bullets of items in unordered lists ('*', '+', or '-',
default: '*').
There are three cases where the primary bullet cannot be used:
bullet is also a valid rule: * - +; this would turn into a thematic
break if serialized with three primary bullets; bulletOther is used for
the last itembullet is the
same character as rule: - ***; this would turn into a single thematic
break if serialized with primary bullets; bulletOther is used for the
item* a\n- b;
bulletOther is used for such listsoptions.bulletOtherMarker to use in certain cases where the primary bullet doesn’t work ('*',
'+', or '-', default: '-' when bullet is '*', '*' otherwise).
Cannot be equal to bullet.
options.bulletOrderedMarker to use for bullets of items in ordered lists ('.' or ')', default:
'.').
There is one case where the primary bullet for ordered items cannot be used:
1. a\n2) b; to solve
that, '.' will be used when bulletOrdered is ')', and '.' otherwiseoptions.closeAtxWhether to add the same number of number signs (#) at the end of an ATX
heading as the opening sequence (boolean, default: false).
options.emphasisMarker to use for emphasis ('*' or '_', default: '*').
options.fenceMarker to use for fenced code ('`' or '~', default: '`').
options.fencesWhether to use fenced code always (boolean, default: true).
The default is to use fenced code if there is a language defined, if the code is
empty, or if it starts or ends in blank lines.
options.incrementListMarkerWhether to increment the counter of ordered lists items (boolean, default:
true).
options.listItemIndentHow to indent the content of list items ('mixed', 'one', or 'tab',
default: 'one').
Either with the size of the bullet plus one space (when 'one'), a tab stop
('tab'), or depending on the item and its parent list ('mixed', uses 'one'
if the item and list are tight and 'tab' otherwise).
options.quoteMarker to use for titles ('"' or "'", default: '"').
options.resourceLinkWhether to always use resource links (boolean, default: false).
The default is to use autolinks (<https://example.com>) when possible
and resource links ([text](url)) otherwise.
options.ruleMarker to use for thematic breaks ('*', '-', or '_', default: '*').
options.ruleRepetitionNumber of markers to use for thematic breaks (number, default: 3, min: 3).
options.ruleSpacesWhether to add spaces between markers in thematic breaks (boolean, default:
false).
options.setextWhether to use setext headings when possible (boolean, default: false).
The default is to always use ATX headings (# heading) instead of setext
headings (heading\n=======).
Setext headings cannot be used for empty headings or headings with a rank of
three or more.
options.strongMarker to use for strong ('*' or '_', default: '*').
options.tightDefinitionsWhether to join definitions without a blank line (boolean, default: false).
The default is to add blank lines between any flow (“block”) construct.
Turning this option on is a shortcut for a [Join][api-join] function like so:
function joinTightDefinitions(left, right) {
if (left.type === 'definition' && right.type === 'definition') {
return 0
}
}
options.handlersHandle particular nodes ([Handlers][api-handlers], optional).
options.joinHow to join blocks ([Array<Join>][api-join], optional).
options.unsafeSchemas that define when characters cannot occur
([Array<Unsafe>][api-unsafe], optional).
options.extensionsList of extensions (Array<Options>, default: []).
Each extension is an object with the same interface as Options itself.
SafeConfigConfiguration passed to state.safe (TypeScript type).
before (string)
— characters before this (guaranteed to be one, can be more)after (string)
— characters after this (guaranteed to be one, can be more)encode (Array<string>, optional)
— extra characters that must be encoded (as character references) instead
of escaped (character escapes).
Only ASCII punctuation will use character escapes, so you never need to
pass non-ASCII-punctuation hereStateInfo passed around about the current state (TypeScript type).
stack ([Array<ConstructName>][api-construct-name])
— stack of constructs we’re inindexStack (Array<number>)
— positions of child nodes in their parentsassociationId ((node: Association) => string)
— get an identifier from an association to match it to others (see
[Association][association])enter ((construct: ConstructName) => () => undefined)
— enter a construct (returns a corresponding exit function)
(see [ConstructName][api-construct-name])indentLines ((value: string, map: Map) => string)
— pad serialized markdown (see [Map][api-map])compilePattern ((pattern: Unsafe) => RegExp)
— compile an unsafe pattern to a regex (see [Unsafe][api-unsafe])containerFlow ((parent: Node, info: Info) => string)
— serialize flow children (see [Info][api-info])containerPhrasing ((parent: Node, info: Info) => string)
— serialize phrasing children (see [Info][api-info])createTracker ((info: Info) => Tracker)
— track positional info in the output (see [Info][api-info],
[Tracker][api-tracker])safe ((value: string, config: SafeConfig) => string)
— make a string safe for embedding (see [SafeConfig][api-safe-config])options ([Options][api-options])
— applied user configurationunsafe ([Array<Unsafe>][api-unsafe])
— applied unsafe patternsjoin ([Array<Join>][api-join])
— applied join handlershandle ([Handle][api-handle])
— call the configured handler for the given nodehandlers ([Handlers][api-handlers])
— applied handlersbulletCurrent (string or undefined)
— list marker currently in usebulletLastUsed (string or undefined)
— list marker previously in useTrackerTrack positional info in the output (TypeScript type).
This info isn’t used yet but such functionali
browse all types & interfaces →
$ claude mcp add mdast-util-to-markdown \
-- python -m otcore.mcp_server <graph>