/** * md-to-docx.js * ------------------------------------------------------------ * Markdownファイル(見出し/表/太字/リンク/箇条書き/水平線程度の書式)を * 同名の .docx として書き出します。Markdown→HTML変換はmd-to-pdf.jsの * markdownToHtml()を再利用(外部npmパッケージ非依存)。 * docx化にはOS標準のMicrosoft Word(COM自動化)を使用します。 * ClaudePleasanter直下に置く共通実装。全プロジェクトの薄いラッパーから require される。 * 入出力パスは引数で受け取るのみのためbaseDir/layoutに依存しない。 * * 使い方: * node md-to-docx.js ./docs/site-475384_overview.md * node md-to-docx.js ./docs/*.md (シェルのグロブ展開に依存。複数ファイル可) * * 出力: * 入力と同じフォルダに {同名}.docx を生成(中間HTML・PowerShellスクリプトは生成後に削除) * ------------------------------------------------------------ */ const fs = require("fs"); const path = require("path"); const os = require("os"); const { execFileSync } = require("child_process"); const { markdownToHtml } = require("./md-to-pdf.js"); const CSS = ` body { font-family: "Yu Gothic", "Meiryo", "Hiragino Sans", sans-serif; font-size: 10.5pt; line-height: 1.7; color: #1a1a1a; } h1 { font-size: 18pt; border-bottom: 3px solid #2a5599; padding-bottom: 6px; margin-top: 0; } h2 { font-size: 14pt; border-bottom: 1px solid #ccc; padding-bottom: 4px; margin-top: 28px; color: #2a5599; } h3 { font-size: 12pt; margin-top: 20px; } table { border-collapse: collapse; width: 100%; margin: 10px 0 16px; font-size: 9.5pt; } th, td { border: 1px solid #999; padding: 5px 8px; text-align: left; vertical-align: top; } th { background-color: #2a5599; color: #fff; } ul, ol { margin: 6px 0; padding-left: 22px; } li { margin: 3px 0; } p { margin: 8px 0; } code { background: #eee; padding: 1px 4px; border-radius: 3px; } hr { border: none; border-top: 1px solid #ccc; margin: 20px 0; } a { color: #2a5599; } `; function escapeHtml(s) { return s.replace(/&/g, "&").replace(//g, ">"); } // PowerShellのシングルクォート文字列リテラル用エスケープ('を''にする) function psSingleQuote(s) { return `'${String(s).replace(/'/g, "''")}'`; } function convertOne(mdPath) { const srcPath = path.resolve(mdPath); if (!fs.existsSync(srcPath)) { console.error(`[エラー] ファイルが見つかりません: ${srcPath}`); return false; } const mdText = fs.readFileSync(srcPath, "utf-8"); const titleMatch = mdText.match(/^#\s+(.+)$/m); const title = titleMatch ? titleMatch[1] : path.basename(srcPath); const bodyHtml = markdownToHtml(mdText); const htmlDoc = `