SpecWorks.MarkMyWord 0.4.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package SpecWorks.MarkMyWord --version 0.4.0
                    
NuGet\Install-Package SpecWorks.MarkMyWord -Version 0.4.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SpecWorks.MarkMyWord" Version="0.4.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SpecWorks.MarkMyWord" Version="0.4.0" />
                    
Directory.Packages.props
<PackageReference Include="SpecWorks.MarkMyWord" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SpecWorks.MarkMyWord --version 0.4.0
                    
#r "nuget: SpecWorks.MarkMyWord, 0.4.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SpecWorks.MarkMyWord@0.4.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SpecWorks.MarkMyWord&version=0.4.0
                    
Install as a Cake Addin
#tool nuget:?package=SpecWorks.MarkMyWord&version=0.4.0
                    
Install as a Cake Tool

MarkMyWord

A .NET 9 library for converting CommonMark markdown to Microsoft Word (.docx) documents.

Features

MarkMyWord converts markdown documents to Word format using the Open XML SDK. It supports the CommonMark specification including:

Currently Supported

Block Elements

  • Headings (ATX: # H1 through ###### H6, Setext: underlined)
  • Paragraphs
  • Code blocks (fenced with ``` and indented)
  • Block quotes (>)
  • Thematic breaks (---, ***, ___)
  • Lists (ordered, unordered, nested with proper indentation)
  • Tables (with headers, borders, and shading)

Inline Elements

  • Bold (**text** or __text__)
  • Italic (*text* or _text_)
  • Bold + Italic (***text***)
  • Inline code (`code`)
  • Links ([text](url))
  • Images (![alt](url) - supports local files and URLs with fallback)
  • Hard line breaks (two spaces or \ at end of line)

Styling

  • Customizable fonts and colors
  • Configurable heading styles
  • Code syntax highlighting for JSON, TypeSpec, and Bash
  • Automatic spell/grammar check suppression for code blocks

Coming Soon

  • Task lists
  • Footnotes
  • Definition lists

Installation

dotnet add package MarkMyWord

Quick Start

Basic Usage

using MarkMyWord;

// Convert markdown string to .docx file
string markdown = "# Hello World\n\nThis is **bold** text.";
MarkdownConverter.ConvertToDocx(markdown, "output.docx");

Convert to Byte Array

// Get the document as a byte array (useful for web scenarios)
byte[] docxBytes = MarkdownConverter.ConvertToDocxBytes(markdown);

Stream-based Conversion

// Convert from stream to stream
using var inputStream = File.OpenRead("input.md");
using var outputStream = File.Create("output.docx");
MarkdownConverter.ConvertToDocx(inputStream, outputStream);

Async Conversion

// Async conversion
await MarkdownConverter.ConvertToDocxAsync(markdown, "output.docx");

Lists

// Unordered list
string unorderedList = @"
# Shopping List
- Apples
- Bananas
- Oranges
  - Naval oranges
  - Blood oranges
";

MarkdownConverter.ConvertToDocx(unorderedList, "shopping.docx");

// Ordered list
string orderedList = @"
# Instructions
1. Preheat oven to 350°F
2. Mix ingredients
3. Bake for 30 minutes
   1. Check at 25 minutes
   2. Test with toothpick
4. Let cool
";

MarkdownConverter.ConvertToDocx(orderedList, "instructions.docx");

Command-Line Interface

MarkMyWord includes a powerful CLI for converting markdown files from the command line.

Installation

dotnet tool install --global SpecWorks.MarkMyWord.CLI

Or run directly from the project:

dotnet run --project src/MarkMyWord.CLI/MarkMyWord.CLI.csproj -- [command] [options]

Usage

Basic conversion:

markmyword convert -i README.md

Specify output file:

markmyword convert -i input.md -o output.docx

Custom font and size:

markmyword convert -i document.md --font "Times New Roman" --font-size 12

Use custom style configuration:

markmyword convert -i document.md --style custom-style.json

Verbose output:

markmyword convert -i document.md -v

Force overwrite:

markmyword convert -i document.md --force

View version:

markmyword version

Get help:

markmyword --help
markmyword convert --help

CLI Options

Option Alias Description
--input -i Input markdown file path (required)
--output -o Output .docx file path (default: same as input)
--verbose -v Enable verbose output
--font -f Default font name
--font-size -s Default font size (6-72 points)
--style - Path to JSON style configuration file
--force - Overwrite output file if it exists

Advanced Usage

Custom Styling

using MarkMyWord.Configuration;

var options = new ConversionOptions
{
    Styles = new StyleConfiguration
    {
        DefaultFontName = "Georgia",
        DefaultFontSize = 12,
        CodeFontName = "Fira Code",
        CodeFontSize = 10,
        CodeBackgroundColor = "F5F5F5",
        QuoteLeftBorderColor = "4A90E2",
        QuoteBackgroundColor = "EEF7FF"
    }
};

MarkdownConverter.ConvertToDocx(markdown, "output.docx", options);

Custom Heading Styles

var options = new ConversionOptions
{
    Styles = new StyleConfiguration
    {
        HeadingStyles = new[]
        {
            new HeadingStyle
            {
                Level = 1,
                FontSize = 24,
                Bold = true,
                Color = "2E74B5",
                SpacingBeforeTwips = 480,  // 1/3 inch
                SpacingAfterTwips = 240    // 1/6 inch
            },
            // ... configure levels 2-6
        }
    }
};

JSON Style Configuration

You can define styles in a JSON file and load them using the CLI or programmatically:

custom-style.json:

{
  "styles": {
    "defaultFontName": "Georgia",
    "defaultFontSize": 12,
    "headingStyles": [
      {
        "level": 1,
        "fontSize": 28,
        "bold": true,
        "color": "2E74B5",
        "spacingBeforeTwips": 480,
        "spacingAfterTwips": 240
      },
      {
        "level": 2,
        "fontSize": 20,
        "bold": true,
        "color": "2E74B5",
        "spacingBeforeTwips": 400,
        "spacingAfterTwips": 200
      },
      {
        "level": 3,
        "fontSize": 16,
        "bold": true,
        "color": "1F4D78",
        "spacingBeforeTwips": 320,
        "spacingAfterTwips": 160
      }
    ],
    "codeFontName": "Fira Code",
    "codeFontSize": 10,
    "codeBackgroundColor": "282C34",
    "quoteLeftBorderColor": "4A90E2",
    "quoteLeftBorderWidth": 4,
    "quoteBackgroundColor": "EEF7FF",
    "listIndentationTwips": 720
  }
}

Use with CLI:

markmyword convert -i document.md --style custom-style.json

Load programmatically:

using System.Text.Json;

var json = File.ReadAllText("custom-style.json");
var config = JsonSerializer.Deserialize<ConversionOptions>(json);
MarkdownConverter.ConvertToDocx(markdown, "output.docx", config);

Notes:

  • Colors are hex values without the # prefix
  • Spacing values are in twips (1440 twips = 1 inch)
  • Font sizes are in points

Document Metadata

var options = new ConversionOptions
{
    DocumentTitle = "My Document",
    Author = "John Doe",
    Subject = "Technical Documentation"
};

MarkdownConverter.ConvertToDocx(markdown, "output.docx", options);

Architecture

MarkMyWord uses a three-stage conversion pipeline:

  1. Parse: Markdown is parsed into an Abstract Syntax Tree (AST) using Markdig
  2. Render: The AST is traversed and converted to OpenXML elements using specialized renderers
  3. Style: Styles are applied and the document is saved using DocumentFormat.OpenXml
Markdown Text
     ↓
  Markdig Parser
     ↓
   AST (Syntax Tree)
     ↓
OpenXmlRenderer
     ↓
  OpenXML Elements
     ↓
 Word Document (.docx)

Project Structure

MarkMyWord/
├── src/
│   ├── MarkMyWord/                    # Core library
│   │   ├── MarkdownConverter.cs       # Public API
│   │   ├── Converters/
│   │   │   ├── OpenXmlRenderer.cs     # Main renderer
│   │   │   ├── BlockRenderers/        # Block element renderers
│   │   │   │   ├── CodeBlockRenderer.cs  # Code block rendering
│   │   │   │   ├── ListRenderer.cs    # List rendering
│   │   │   │   └── TableRenderer.cs   # Table rendering
│   │   │   └── InlineRenderers/       # Inline element renderers
│   │   │       └── LinkInlineRenderer.cs  # Links & images
│   │   ├── SyntaxHighlighting/        # Syntax highlighting
│   │   │   ├── ISyntaxHighlighter.cs  # Highlighter interface
│   │   │   ├── ColorCodeHighlighter.cs   # JSON highlighting
│   │   │   ├── TypeSpecHighlighter.cs    # TypeSpec highlighting
│   │   │   ├── BashHighlighter.cs     # Bash/Shell highlighting
│   │   │   └── SyntaxHighlighterFactory.cs
│   │   ├── OpenXml/
│   │   │   ├── DocumentBuilder.cs     # OpenXML document builder
│   │   │   ├── StyleManager.cs        # Style management
│   │   │   └── ListManager.cs         # List numbering management
│   │   └── Configuration/             # Configuration classes
│   └── MarkMyWord.CLI/                # Command-line tool
└── tests/
    └── MarkMyWord.Tests/              # Unit tests (29 tests)

Requirements

  • .NET 9.0 or later
  • Dependencies:
    • Markdig 0.37.0
    • DocumentFormat.OpenXml 3.1.0
    • ColorCode.Core 2.0.15

Building from Source

git clone https://github.com/yourusername/MarkMyWord.git
cd MarkMyWord
dotnet build
dotnet test

Examples

Convert a README file

var markdown = File.ReadAllText("README.md");
MarkdownConverter.ConvertToDocx(markdown, "README.docx");

Lists Example

string markdown = @"
# Shopping List

## Groceries
- Milk
- Eggs
- Bread

## Tasks
1. Buy groceries
2. Clean house
3. Do laundry
   - Whites
   - Colors
";

MarkdownConverter.ConvertToDocx(markdown, "shopping-list.docx");

Images Example

string markdown = @"
# Product Documentation

![Product Logo](logo.png)

Our product features:
![Feature 1](https://example.com/feature1.png)
![Feature 2](./images/feature2.jpg)
";

MarkdownConverter.ConvertToDocx(markdown, "product-doc.docx");

Tables Example

string markdown = @"
# Sales Report

| Product | Q1 Sales | Q2 Sales | Total |
|---------|----------|----------|-------|
| Widget A | $1,000 | $1,200 | $2,200 |
| Widget B | $850 | $900 | $1,750 |
| Widget C | $1,500 | $1,600 | $3,100 |
";

MarkdownConverter.ConvertToDocx(markdown, "sales-report.docx");

Syntax Highlighting

MarkMyWord supports syntax highlighting for code blocks, making code more readable in Word documents:

Supported Languages:

  • JSON - Property names, strings, numbers, keywords (true/false/null)
  • TypeSpec - Keywords, types, decorators, comments
  • Bash/Shell - Commands, keywords, variables, strings, comments

Example:

string markdown = @"
# API Response

```json
{
  ""name"": ""MarkMyWord"",
  ""version"": ""0.2.0"",
  ""enabled"": true
}
#!/bin/bash
echo ""Converting files...""
for file in *.md; do
    markmyword convert -i ""$file""
done

";

MarkdownConverter.ConvertToDocx(markdown, "highlighted.docx");


**Features:**
- Colors optimized for grey code block backgrounds
- Automatic spell/grammar check suppression (no red squiggles!)
- Trailing empty lines automatically removed
- Property names vs values distinguished in JSON

**Disable syntax highlighting:**
```csharp
var options = new ConversionOptions
{
    EnableSyntaxHighlighting = false
};

MarkdownConverter.ConvertToDocx(markdown, "plain-code.docx", options);

Custom syntax colors:

var options = new ConversionOptions
{
    Styles = new StyleConfiguration
    {
        SyntaxColorScheme = new SyntaxColorScheme
        {
            KeywordColor = "0000FF",     // Blue
            StringColor = "A31515",      // Red
            NumberColor = "098658",      // Green
            CommentColor = "6A9955",     // Green
            TypeColor = "4EC9B0",        // Cyan
            FunctionColor = "C4A000"     // Gold
        }
    }
};

Convert with custom code block styling

var options = new ConversionOptions
{
    Styles = new StyleConfiguration
    {
        CodeFontName = "Consolas",
        CodeFontSize = 9,
        CodeBackgroundColor = "F5F5F5"  // Light grey
    }
};

string code = @"
# Code Example

```json
{
  ""message"": ""Hello, World!""
}

";

MarkdownConverter.ConvertToDocx(code, "code.docx", options);


## Testing

The library includes comprehensive unit tests covering all supported markdown syntax:

```bash
dotnet test

Current test coverage (29 tests):

  • ✅ Basic paragraph conversion
  • ✅ Headings (levels 1-6)
  • ✅ Bold and italic text
  • ✅ Inline code
  • ✅ Code blocks with language labels
  • ✅ Hyperlinks
  • Lists (ordered, unordered, nested, mixed, with formatting)
  • Images (with fallback for missing images)
  • Tables (headers, multiple rows, shading, borders)

Specifications

MarkMyWord implements:

Contributing

Contributions are welcome! Areas for contribution:

  • Task lists and checkboxes
  • Footnotes and references
  • Definition lists
  • Extended markdown features
  • Performance optimizations
  • Additional tests

License

MIT License - See LICENSE file for details

Acknowledgments

Status

🚀 Beta - Core functionality and CLI are fully working with comprehensive CommonMark support.

Fully supported:

  • Headings, paragraphs, emphasis (bold/italic)
  • Code blocks (fenced and indented) with syntax highlighting (JSON, TypeSpec, Bash)
  • Inline code
  • Links and hyperlinks
  • Block quotes
  • Horizontal rules / thematic breaks
  • Lists (ordered, unordered, nested with proper numbering)
  • Images (local files and URLs with fallback support)
  • Tables (with headers, borders, and shading)
  • Command-line interface with full options
  • Spell/grammar check suppression for code

Coming soon: Task lists, footnotes, definition lists


Generated with ❤️ using Claude Code

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.9.0 83 4/9/2026
0.8.0 93 3/20/2026
0.8.0-preview3 85 3/18/2026
0.8.0-preview2 81 3/18/2026
0.8.0-preview 85 3/18/2026
0.7.0 97 3/14/2026
0.6.0 85 3/7/2026
0.5.0 121 1/24/2026
0.4.0 99 1/19/2026
0.3.0 104 1/15/2026
0.1.0 112 1/2/2026