NAME

markdown-adoc - Convert Markdown (GFM + kramdown extensions) to AsciiDoc

SYNOPSIS

markdown-adoc [OPTIONS] FILE

markdown-adoc [OPTIONS] -

DESCRIPTION

markdown-adoc reads Markdown input and writes AsciiDoc output suitable for use with Asciidoctor. The converter targets practical Markdown as found in real technical documentation: GitHub-Flavored Markdown (GFM) plus kramdown extensions (definition lists, footnotes).

FILE may be a path to a Markdown file or - for stdin.

By default, output is written beside the input using the same base name with a .adoc extension (replacing .md, .markdown, .mdown, .mkd, or .mkdn). Use -o or --output to override this or use - for stdout.

OPTIONS

-o, --output path|-

Write output to path or to stdout when set to -.

Default: replace the input extension with .adoc.

-a, --attribute KEY=VALUE

Set an AsciiDoc attribute in the output document header. Repeatable.

Variants:

-a KEY=VALUE    Set KEY to VALUE.
-a KEY          Set KEY with empty value.
-a KEY!         Unset KEY (emit C<:KEY!:>).
--imagesdir DIR

Set the imagesdir option for the conversion (propagated to attribute processing and link/image rewriting).

--auto-ids

Enable auto-generation of heading IDs ([[_heading_text]] anchors). By default, heading IDs are not emitted unless the input contains explicit <a name="id"></a> anchors.

--idprefix STRING

Set the prefix for auto-generated heading IDs (default: _).

Example: --idprefix sect- produces [[sect-introduction]].

--idseparator CHAR

Set the word separator for auto-generated heading IDs (default: _).

Example: --idseparator - produces [[_heading-text]].

--wrap MODE

Control how paragraph text lines are emitted in the output.

preserve (default)

Emit lines exactly as they appear in the source.

none

Join all lines of a paragraph into a single line (unwrap).

ventilate

Join lines but re-break at sentence boundaries (after ., ?, !, ; followed by whitespace).

Wrap mode does not affect code blocks, literal blocks, or passthrough blocks.

--man

Display this full man-page help and exit.

-h, --help

Display short usage help and exit.

-v, --version

Display version number and exit.

EXIT STATUS

Returns 0 on success. Errors are reported to stderr and the program exits with a non-zero status.

COMMONMARK COMPATIBILITY

markdown-adoc is not a full CommonMark spec implementation. It targets the practical subset of Markdown found in real technical documentation and accepts GFM + kramdown extensions. This section documents areas where the converter intentionally deviates from or extends the spec.

Supported Features

All features listed in Text::MarkdownAdoc are supported:

  • Headings

    ATX (# prefix) and setext (===/--- underline) styles, levels 1--6.

  • Paragraphs

    Accumulated across line continuations; blank-line separated.

  • Hard line breaks

    Trailing two spaces or trailing backslash (\) produce a + marker.

  • Inline formatting

    Bold (** / __), italic (* / _), code spans (`), strikethrough (~~).

  • Links

    Inline [text](url), reference-style [text][ref], shorthand [ref], autolinks <url>.

  • Images

    Inline ![alt](src) and reference-style ![alt][ref].

  • Fenced code blocks

    ```lang / ~~~ with optional language annotation.

  • Indented code blocks

    Four-space or tab indentation (outside list context only).

  • Blockquotes

    Nested > quotes, scaled to ____ / ______ AsciiDoc delimiters.

  • Lists

    Unordered (-, *, +), ordered (1., 2)), task lists ([ ], [x]), nested and mixed lists.

  • Tables

    GFM pipe tables with header row and alignment (:---, :---:, ---:).

  • Thematic breaks

    ---, ***, ___ and spaced variants.

  • Front matter

    YAML --- delimited block at document start extracted as AsciiDoc header attributes (:key: value). The title key becomes the document title if the body has no level-1 heading.

  • Smart quotes

    Unicode smart quotes (U+201C/D, U+2018/9) converted to AsciiDoc typographic syntax.

  • HTML entities

    &nbsp; converted; other entities pass through.

  • Inline HTML

    Known tags (strong, em, code, del, mark, sup, sub, br) converted to AsciiDoc equivalents. Unknown tags wrapped in ++++ passthrough delimiters.

  • Block HTML

    HTML comments become AsciiDoc comments (// or ////). Other block-level HTML is wrapped in passthrough blocks (++++).

  • Diagram blocks

    Fenced blocks with plantuml or mermaid language tags use .... delimiters.

  • Math

    Inline $...$, block $$...$$, and fenced ```math blocks converted to AsciiDoc stem blocks. The :stem: latexmath attribute is injected automatically when math is detected.

Known Limitations

  • No spec-level compliance

    The converter does not implement every CommonMark edge case for delimiter runs, link label matching, or entity handling. It makes pragmatic choices that work for technical documents.

  • Underscore-based italic

    Only * for italic and ** for bold are recommended in practice because the converter's _ italic matching uses word-boundary constraints to avoid breaking identifiers like snake_case. Full CommonMark flanking-delimiter matching is not implemented.

  • Reference link label matching

    Labels are matched case-insensitively with whitespace normalization but do not implement the full CommonMark link label normalization rules (Unicode folding, entity expansion).

  • No raw HTML passthrough semantics

    Block HTML is emitted inside ++++ passthrough blocks rather than being converted to native AsciiDoc equivalents. This preserves the HTML but may not render identically in all Asciidoctor backends.

ADVANCED FEATURES: MARKDOWN REPRESENTATION

This section explains how advanced (non-native Markdown) features should be written in the Markdown source to produce the correct AsciiDoc output. These conventions are based on kramdown syntax and the target AsciiDoc structure.

Definition Lists (Description Lists)

Standard form (single term with definition text on following lines)

Markdown input:

 Term
 : Definition text here that describes the term.

AsciiDoc output:

 Term:: Definition text here that describes the term.

Bold-term form (term and definition on same line)

Markdown input:

 **Term**:: Definition text here.

AsciiDoc output:

 Term:: Definition text here.

Multiple definitions for one term

Use multiple : lines:

Markdown input:

 Term
 : First definition.
 : Second definition.

AsciiDoc output:

 Term:: First definition.
 +
 Second definition.

Multi-level (nested) definition lists

Nesting is indicated by the number of colons after the term:

Markdown input:

 **Outer Term**:: Outer definition text.
 **Inner Term**::: Inner definition text.

AsciiDoc output:

 Outer Term:: Outer definition text.
 Inner Term::: Inner definition text.

The level of nesting corresponds to the number of colons (:: for level 1, ::: for level 2, :::: for level 3, etc.).

Footnotes

Simple footnote

Markdown input:

 Here is a sentence.[^1]

 [^1]: This is the footnote text.

AsciiDoc output:

 Here is a sentence.footnote:fn1[This is the footnote text.]

Multiple references to the same footnote

Markdown input:

 First ref.[^1] Second ref.[^1]

 [^1]: The footnote text.

AsciiDoc output:

 First ref.footnote:fn1[The footnote text.] Second ref.footnote:fn1[]

The first reference includes the full footnote text; subsequent references use an empty [].

Footnotes with inline formatting

Markdown input:

 [^a]: This has **bold** and _italic_ text.

Inline formatting inside the footnote definition is preserved in the output.

Admonitions

Paragraph-style admonition

Markdown input:

 Note: This is an informational note.

AsciiDoc output:

 NOTE: This is an informational note.

The label is case-insensitive. Supported labels: Note, Tip, Important, Warning, Caution.

Multi-paragraph admonition (blockquote form)

Markdown input:

 > **Note:** This is the first paragraph.
 >
 > This is the second paragraph of the note.

AsciiDoc output:

 [NOTE]
 ====
 This is the first paragraph.
 This is the second paragraph of the note.
 ====

The bold label **Note:** must appear on the first line of the blockquote. The blockquote marker > is consumed by the converter.

Diagrams

PlantUML block

Markdown input:

 ```plantuml
 Alice -> Bob: Hello
 Bob -> Alice: Hi
 ```

AsciiDoc output:

 [plantuml]
 ....
 Alice -> Bob: Hello
 Bob -> Alice: Hi
 ....

Mermaid block

Same convention with ```mermaid.

Math

Inline math

Markdown input:

 The formula $E = mc^2$ is famous.

AsciiDoc output:

 The formula stem:[E = mc^2] is famous.

The :stem: latexmath attribute is automatically added to the document header when math is present.

Block math

Markdown input:

 $$
 E = mc^2
 $$

AsciiDoc output:

 [stem]
 ++++
 E = mc^2
 ++++

Fenced math block

Markdown input:

 ```math
 E = mc^2
 ```

AsciiDoc output (same as block C<$$>):

 [stem]
 ++++
 E = mc^2
 ++++

Front Matter

YAML front matter at the top of the document is extracted as AsciiDoc header attributes:

Markdown input:

 ---
 title: My Document
 author: Jane Doe
 toc: auto
 ---

 # Introduction

 This is the body.

AsciiDoc output (body has a level-1 heading, so C<title> is not reused):

 :author: Jane Doe
 :toc: auto

 = Introduction

 This is the body.

When the body does not contain a level-1 heading, the title key becomes the document title:

:author: Jane Doe
:toc: auto

= My Document

This is the body.

Cross-References

Markdown input:

 [See the introduction](#introduction)

AsciiDoc output:

 <<introduction,See the introduction>>

.md file links are rewritten to .adoc xref:

Markdown input:

 [Reference](other.md)

AsciiDoc output:

 xref:other.adoc[Reference]

Heading IDs (Auto-Generated)

When --auto-ids is used, headings without anchors get generated IDs:

Markdown input:

 ## Introduction

AsciiDoc output (with C<--auto-ids>):

 [[_introduction]]
 == Introduction

Heading IDs (Explicit)

Markdown input:

 ## <a name="intro"></a>Introduction

AsciiDoc output:

 [[intro]]
 == Introduction

SEE ALSO

Text::MarkdownAdoc, Text::MarkdownAdoc::Parser, Text::MarkdownAdoc::Inline, Text::MarkdownAdoc::Refs, Text::AsciidocDown, Asciidoctor

For a full list of supported Markdown constructs, conversion mappings, known limitations, and differences from kramdown-asciidoc, see COMPATIBILITY_REPORT.adoc included in the distribution.

AUTHOR

Sandor Patocs

LICENSE

This program is distributed under the same terms as Perl itself.