Table of Contents

Class DocxToMarkdownConverter

Namespace
DocToolkit
Assembly
DocToolkit.dll

Converts a Word (.docx) package to Markdown, keeping the structure ExtractText(byte[]) throws away: a heading becomes #, a table becomes a pipe table. Use ExtractText when flat text is what you want.

The result is self-contained. Images in the source document are embedded as data: URIs rather than written beside the output and referenced by path, so the string this returns stands on its own.

public static class DocxToMarkdownConverter
Inheritance
DocxToMarkdownConverter
Inherited Members

Methods

Convert(byte[])

Converts the .docx in docx to Markdown.

public static string Convert(byte[] docx)

Parameters

docx byte[]

The document to convert.

Returns

string

Examples

// Structure survives: a heading becomes "#", a table becomes a pipe table. ExtractText, by
// contrast, returns the same words as flat lines with no markup at all.
string markdown = DocxToMarkdownConverter.Convert(docx);

Exceptions

ArgumentNullException

docx is null.

ArgumentException

docx is empty.

DocumentConversionException

The document could not be converted.

ConvertAsync(Stream, CancellationToken)

Reads a .docx from source and returns it as Markdown.

source is read to its end and is not disposed, closed or sought, so it may be forward-only — an HTTP request body, for instance.

public static Task<string> ConvertAsync(Stream source, CancellationToken ct = default)

Parameters

source Stream

The stream the .docx package is read from.

ct CancellationToken

Cancels the read.

Returns

Task<string>

Exceptions

ArgumentNullException

source is null.

ArgumentException

source is not readable or held no bytes.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The document could not be converted.

ConvertWithReport(byte[])

Converts the .docx in docx to Markdown, and reports what the conversion could not carry across.

public static ConversionResult<string> ConvertWithReport(byte[] docx)

Parameters

docx byte[]

The document to convert.

Returns

ConversionResult<string>

Remarks

Convert(byte[]) returns the same Markdown and is unchanged.

The conversion runs twice here, deliberately. The report and the string come from two different upstream entry points, and the report-carrying one renders a MarkdownDoc whose own output is not byte-identical to what Convert(byte[]) produces — measured 2026-08-13: different line endings and a trailing newline. Rendering from the report would therefore have changed this converter's output for anyone who switched overloads. Running the plain conversion for the value keeps the two overloads returning exactly the same string, and the extra pass is paid only by a caller who asked for the report. Calling both on one loaded document is measured safe: the second call returns what a fresh load returns.

The result is always usable: this reports loss, it does not refuse.

Exceptions

ArgumentNullException

docx is null.

ArgumentException

docx is empty.

DocumentConversionException

The document could not be converted.

ConvertWithReportAsync(Stream, CancellationToken)

Reads a .docx from source and converts it to Markdown, reporting what the conversion could not carry across.

source is read to its end and is not disposed, closed or sought.

public static Task<ConversionResult<string>> ConvertWithReportAsync(Stream source, CancellationToken ct = default)

Parameters

source Stream

The stream the .docx package is read from.

ct CancellationToken

Cancels the read.

Returns

Task<ConversionResult<string>>

Remarks

Convert(byte[]) returns the same Markdown and is unchanged.

The conversion runs twice here, deliberately. The report and the string come from two different upstream entry points, and the report-carrying one renders a MarkdownDoc whose own output is not byte-identical to what Convert(byte[]) produces — measured 2026-08-13: different line endings and a trailing newline. Rendering from the report would therefore have changed this converter's output for anyone who switched overloads. Running the plain conversion for the value keeps the two overloads returning exactly the same string, and the extra pass is paid only by a caller who asked for the report. Calling both on one loaded document is measured safe: the second call returns what a fresh load returns.

The result is always usable: this reports loss, it does not refuse.

Exceptions

ArgumentNullException

docx is null.

ArgumentException

docx is empty.

DocumentConversionException

The document could not be converted.

ArgumentException

source is not readable or held no bytes.

OperationCanceledException

ct was cancelled.