Skip to main content
Glama

convert_markdown_to_docx

Convert Markdown files to professionally styled Word documents with theme options, table of contents, and formatting preservation.

Instructions

Enhanced Markdown to DOCX conversion with professional styling and theme support. Preserves formatting, supports tables, lists, headings, and inline formatting with beautiful Word document output. Output directory is controlled by OUTPUT_DIR environment variable. Files will be automatically saved to OUTPUT_DIR with auto-generated names.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
markdownPathYesMarkdown file path to convert
themeNoTheme to applyprofessional
includeTableOfContentsNoGenerate table of contents
preserveStylesNoPreserve Markdown formatting and styles

Implementation Reference

  • Exported handler function for the 'convert_markdown_to_docx' tool. Creates converter instance and calls the main conversion method.
    export async function convertMarkdownToDocx( inputPath: string, options: MarkdownToDocxOptions = {} ): Promise<MarkdownToDocxResult> { const converter = new MarkdownToDocxConverter(); return await converter.convertMarkdownToDocx(inputPath, options); }
  • Core implementation of Markdown to DOCX conversion within the converter class: reads file, parses Markdown elements (headings, paragraphs, tables, code blocks, etc.), applies themes and styles using docx library, generates and returns DOCX buffer.
    async convertMarkdownToDocx( inputPath: string, options: MarkdownToDocxOptions = {} ): Promise<MarkdownToDocxResult> { try { this.options = { preserveStyles: true, theme: 'default', includeTableOfContents: false, debug: false, ...options, }; if (this.options.debug) { console.log('๐Ÿš€ ๅผ€ๅง‹ Markdown ๅˆฐ DOCX ่ฝฌๆข...'); console.log('๐Ÿ“„ ่พ“ๅ…ฅๆ–‡ไปถ:', inputPath); console.log('๐ŸŽจ ไฝฟ็”จไธป้ข˜:', this.options.theme); } // ่ฏปๅ– Markdown ๆ–‡ไปถ const markdownContent = await fs.readFile(inputPath, 'utf-8'); // ่งฃๆž Markdown ๅ†…ๅฎน const parsedElements = await this.parseMarkdown(markdownContent); // ็”Ÿๆˆ DOCX ๆ–‡ๆกฃ const docxDocument = await this.generateDocxDocument(parsedElements); // ็”Ÿๆˆๆ–‡ๆกฃ็ผ“ๅ†ฒๅŒบ const docxBuffer = await Packer.toBuffer(docxDocument); // ไฟๅญ˜ๆ–‡ไปถ๏ผˆๅฆ‚ๆžœๆŒ‡ๅฎšไบ†่พ“ๅ‡บ่ทฏๅพ„๏ผ‰ let docxPath: string | undefined; if (this.options.outputPath) { const { validateAndSanitizePath } = require('../security/securityConfig'); const allowedPaths = [process.cwd()]; const validatedPath = validateAndSanitizePath(this.options.outputPath, allowedPaths); if (validatedPath) { docxPath = validatedPath; await fs.writeFile(validatedPath, docxBuffer); } if (this.options.debug) { console.log('โœ… DOCX ๆ–‡ไปถๅทฒไฟๅญ˜:', docxPath); } } // ๅˆ†ๆžๅ†…ๅฎน็ปŸ่ฎก const stats = this.analyzeContent(parsedElements); if (this.options.debug) { console.log('๐Ÿ“Š ่ฝฌๆข็ปŸ่ฎก:', stats); console.log('โœ… Markdown ่ฝฌๆขๅฎŒๆˆ'); } return { success: true, content: docxBuffer, docxPath, metadata: { originalFormat: 'markdown', targetFormat: 'docx', stylesPreserved: this.options.preserveStyles ?? false, theme: this.options.theme ?? 'default', converter: 'markdown-to-docx-converter', contentLength: docxBuffer.length, ...stats, }, }; } catch (error: any) { console.error('โŒ Markdown ่ฝฌๆขๅคฑ่ดฅ:', error.message); return { success: false, error: error.message, }; } }
  • TypeScript interface defining the input parameters/options schema for the conversion tool.
    interface MarkdownToDocxOptions { preserveStyles?: boolean; theme?: 'default' | 'professional' | 'academic' | 'modern'; includeTableOfContents?: boolean; customStyles?: { fontSize?: number; fontFamily?: string; lineSpacing?: number; margins?: { top?: number; bottom?: number; left?: number; right?: number; }; }; outputPath?: string; debug?: boolean; }
  • TypeScript interface defining the output result schema for the tool.
    interface MarkdownToDocxResult { success: boolean; content?: Buffer; docxPath?: string; metadata?: { originalFormat: string; targetFormat: string; stylesPreserved: boolean; theme: string; converter: string; contentLength: number; headingsCount: number; paragraphsCount: number; tablesCount: number; }; error?: string; }
  • Main converter class containing all helper methods for parsing Markdown, generating styled DOCX elements (headings, tables, code blocks, etc.), theme management, and content analysis.
    class MarkdownToDocxConverter { private options: MarkdownToDocxOptions = {}; private themes: Map<string, any>; constructor() { this.themes = new Map(); this.initializeThemes(); } /** * ๅˆๅง‹ๅŒ–้ข„่ฎพไธป้ข˜ */ private initializeThemes(): void { // ้ป˜่ฎคไธป้ข˜ this.themes.set('default', { fontSize: 11, fontFamily: 'Segoe UI', lineSpacing: 1.15, headingStyles: { h1: { size: 16, color: '2F5496', bold: false }, h2: { size: 13, color: '2F5496', bold: false }, h3: { size: 12, color: '1F3763', bold: false }, h4: { size: 11, color: '2F5496', bold: true }, h5: { size: 11, color: '2F5496', bold: true }, h6: { size: 11, color: '2F5496', bold: true }, }, margins: { top: 1440, bottom: 1440, left: 1440, right: 1440 }, // 1 inch = 1440 twips }); // ไธ“ไธšไธป้ข˜ this.themes.set('professional', { fontSize: 12, fontFamily: 'Segoe UI', lineSpacing: 1.5, headingStyles: { h1: { size: 18, color: '000000', bold: true }, h2: { size: 16, color: '000000', bold: true }, h3: { size: 14, color: '000000', bold: true }, h4: { size: 12, color: '000000', bold: true }, h5: { size: 12, color: '000000', bold: true }, h6: { size: 12, color: '000000', bold: true }, }, margins: { top: 1440, bottom: 1440, left: 1440, right: 1440 }, }); // ๅญฆๆœฏไธป้ข˜ this.themes.set('academic', { fontSize: 12, fontFamily: 'Segoe UI', lineSpacing: 2.0, headingStyles: { h1: { size: 14, color: '000000', bold: true }, h2: { size: 13, color: '000000', bold: true }, h3: { size: 12, color: '000000', bold: true }, h4: { size: 12, color: '000000', bold: false }, h5: { size: 12, color: '000000', bold: false }, h6: { size: 12, color: '000000', bold: false }, }, margins: { top: 1440, bottom: 1440, left: 1440, right: 1440 }, }); // ็Žฐไปฃไธป้ข˜ this.themes.set('modern', { fontSize: 11, fontFamily: 'Segoe UI', lineSpacing: 1.2, headingStyles: { h1: { size: 20, color: '0078D4', bold: true }, h2: { size: 16, color: '0078D4', bold: true }, h3: { size: 14, color: '323130', bold: true }, h4: { size: 12, color: '323130', bold: true }, h5: { size: 11, color: '323130', bold: true }, h6: { size: 11, color: '323130', bold: true }, }, margins: { top: 1440, bottom: 1440, left: 1440, right: 1440 }, }); } /** * ไธป่ฝฌๆขๅ‡ฝๆ•ฐ */ async convertMarkdownToDocx( inputPath: string, options: MarkdownToDocxOptions = {} ): Promise<MarkdownToDocxResult> { try { this.options = { preserveStyles: true, theme: 'default', includeTableOfContents: false, debug: false, ...options, }; if (this.options.debug) { console.log('๐Ÿš€ ๅผ€ๅง‹ Markdown ๅˆฐ DOCX ่ฝฌๆข...'); console.log('๐Ÿ“„ ่พ“ๅ…ฅๆ–‡ไปถ:', inputPath); console.log('๐ŸŽจ ไฝฟ็”จไธป้ข˜:', this.options.theme); } // ่ฏปๅ– Markdown ๆ–‡ไปถ const markdownContent = await fs.readFile(inputPath, 'utf-8'); // ่งฃๆž Markdown ๅ†…ๅฎน const parsedElements = await this.parseMarkdown(markdownContent); // ็”Ÿๆˆ DOCX ๆ–‡ๆกฃ const docxDocument = await this.generateDocxDocument(parsedElements); // ็”Ÿๆˆๆ–‡ๆกฃ็ผ“ๅ†ฒๅŒบ const docxBuffer = await Packer.toBuffer(docxDocument); // ไฟๅญ˜ๆ–‡ไปถ๏ผˆๅฆ‚ๆžœๆŒ‡ๅฎšไบ†่พ“ๅ‡บ่ทฏๅพ„๏ผ‰ let docxPath: string | undefined; if (this.options.outputPath) { const { validateAndSanitizePath } = require('../security/securityConfig'); const allowedPaths = [process.cwd()]; const validatedPath = validateAndSanitizePath(this.options.outputPath, allowedPaths); if (validatedPath) { docxPath = validatedPath; await fs.writeFile(validatedPath, docxBuffer); } if (this.options.debug) { console.log('โœ… DOCX ๆ–‡ไปถๅทฒไฟๅญ˜:', docxPath); } } // ๅˆ†ๆžๅ†…ๅฎน็ปŸ่ฎก const stats = this.analyzeContent(parsedElements); if (this.options.debug) { console.log('๐Ÿ“Š ่ฝฌๆข็ปŸ่ฎก:', stats); console.log('โœ… Markdown ่ฝฌๆขๅฎŒๆˆ'); } return { success: true, content: docxBuffer, docxPath, metadata: { originalFormat: 'markdown', targetFormat: 'docx', stylesPreserved: this.options.preserveStyles ?? false, theme: this.options.theme ?? 'default', converter: 'markdown-to-docx-converter', contentLength: docxBuffer.length, ...stats, }, }; } catch (error: any) { console.error('โŒ Markdown ่ฝฌๆขๅคฑ่ดฅ:', error.message); return { success: false, error: error.message, }; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Tele-AI/doc-ops-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server