from multimark import markdown_to_commonmark
markdown_to_commonmark("_hello_ **world**")'*hello* **world**\n'
Parse CommonMark/GFM and render back as normalized CommonMark.
Usage
Parses the input Markdown into an AST and re-renders it as CommonMark. This effectively normalizes the formatting: different but semantically equivalent Markdown inputs (e.g., *italic* vs _italic_, varying list indentation) will produce a canonical output form.
This is useful for round-trip testing, canonical formatting, or cleaning up inconsistently formatted documents. The output of this function, when parsed again, produces the same AST as the original input.
text: strThe Markdown string to parse and normalize. Must be a Python str.
hardbreaks: bool = FalseRender soft line breaks as hard breaks (backslash-newline). By default, this is False.
smart: bool = FalseConvert straight quotes to curly quotes, -- to en-dashes, --- to em-dashes, and ... to ellipses. By default, this is False.
normalize: bool = FalseConsolidate adjacent text nodes in the parsed AST. By default, this is False.
unsafe: bool = FalseAllow raw HTML to pass through. By default, this is False, which replaces raw HTML with a comment placeholder.
footnotes: bool = FalseEnable footnote syntax parsing. By default, this is False.
extensions: Sequence[str] = ()
A sequence of GFM extension names to enable. Valid names are "table", "strikethrough", "autolink", "tagfilter", and "tasklist".
width: int = 0The column at which to wrap output lines. Set to 0 (the default) to disable line wrapping entirely. This is useful for producing line-wrapped output for version-control-friendly diffs.
options: int = 0Options.SMART | Options.UNSAFE). Merged via OR with any boolean keyword arguments set to True. Defaults to 0.
The boolean keyword arguments (smart, unsafe, hardbreaks, etc.) are convenience shortcuts for the most common Options flags. When both styles are provided, they are merged via OR. See markdown_to_html() for a detailed explanation.
strNormalize inconsistent formatting:
'*hello* **world**\n'
Verify round-trip stability (parse, render, re-parse produces the same HTML):
Wrap at 80 columns for version-control-friendly output:
long_document = "This is a long sentence for demonstration. " * 10
print(markdown_to_commonmark(long_document, width=80))This is a long sentence for demonstration. This is a long sentence for
demonstration. This is a long sentence for demonstration. This is a long
sentence for demonstration. This is a long sentence for demonstration. This is a
long sentence for demonstration. This is a long sentence for demonstration. This
is a long sentence for demonstration. This is a long sentence for demonstration.
This is a long sentence for demonstration.