LoginSignup
2
2

複数のMarkdownファイルを連結して、Wordのdocxファイルに変換する方法

Last updated at Posted at 2024-03-30

複数のMarkdownファイルに分かれたリファレンスマニュアルから、ひとつのWord文書を生成したい。そこで、ChatGPTに聞きながらやってみた。

手順は、次の二つに分かれている。

  1. Markdownファイルを連結する
  2. 連結したMarkdownファイルをdocxファイルに変換する

Markdownファイルを連結する

最初の手順は、PoweShellのスクリプトをChatGPTに書いてもらった。

プロンプト

次の条件で、テキストファイルを連結するプログラムを作成して

  • 実行環境:PowerShell

  • ファイル一覧:articles_list.md

  • 入力フォルダ: ./docs

  • 出力ファイル名: concat.md

  • 出力フォルダ: ./docx

  • 処理内容:

    1. ファイル一覧を読み込む
    2. 以下の処理を繰り返す
      2-1. ファイル一覧に書かれたファイルを入力フォルダから読み込む
      2-2. 読み込んだファイルを連結する
    3. 連結したファイルを、出力フォルダに出力ファイル名で出力する

出力されたプログラム

# ファイル一覧を読み込む
$filesList = Get-Content -Path "./articles_list.md"

# 連結するための空の文字列を用意
$concatenatedContent = ""

# 各ファイルの内容を読み込み、連結する
foreach ($file in $filesList) {
    $filePath = "./docs/$file"
    if (Test-Path $filePath) {
        $content = Get-Content -Path $filePath
        $concatenatedContent += $content + "`n" # 改行を追加して連結
    }
    else {
        Write-Warning "Warning: File not found - $filePath"
    }
}

# 出力フォルダが存在しない場合は作成
$outputFolder = "./docx"
if (-not (Test-Path $outputFolder)) {
    New-Item -ItemType Directory -Path $outputFolder
}

# 連結した内容をファイルに出力
$outputFilePath = "$outputFolder/concat.md"
$concatenatedContent | Out-File -FilePath $outputFilePath

Write-Host "Files have been concatenated and saved to $outputFilePath"

改良する

これは楽ちん。ただいくつか問題点もあるので、これを次の条件で修正

  • 文字化けさせない
  • 各ファイルのメタ記述を無視する(先頭5行を削除)
  • 一部の文字列を置換

最終的に、こんなスクリプトになった。

# 複数ファイルの連結プログラム

# ファイル一覧の読み込み
$fileList = Get-Content -Path './articles_list.md' -Encoding UTF8
$inputpath = 'docs'

# 出力フォルダの確認と作成
$outputFolder = './docx'
if (-not (Test-Path $outputFolder)) {
    New-Item -ItemType Directory -Path $outputFolder
}

# 出力ファイルのパス
$outputFile = "$outputFolder/concat.md"

# 出力ファイルの初期化
if (Test-Path $outputFile) {
    Remove-Item $outputFile
}

# 各ファイルを処理
foreach ($file in $fileList) {
    $filePath = "./$inputpath/$file"
    
    # ファイルが存在するか確認
    if (Test-Path $filePath) {
        # ファイルの内容を読み込む、UTF-8を指定
        $content = Get-Content $filePath -Encoding UTF8
        
        # 先頭5行を削除
        $content = $content | Select-Object -Skip 5
        
        # 文字列の置換
        $content = $content -replace '\.\./images/', './images/'
        
        # 出力ファイルに追加、UTF-8を指定
        $content | Out-File -FilePath $outputFile -Append -Encoding UTF8
    }
    else {
        Write-Warning "File not found: $filePath"
    }
}

ページ間のリンクに変換

markdownテキスト中にレベル1の見出しがあると、Word文書に変換したときにブックマークとしてリンクが貼られる。

# abc

上記の見出しがあると[**この部分**](#abc)がリンクになる。

この見出し「# abc」にブックマークが設定される。ただし英数字しか使えない(みたい)。階層が深くなると使えない(かも)。

リンクは、「#」と「abc」の間にスペースを入れない。

そこで、各markdownの冒頭にファイル名と同じ名前で「#(ファイル名)」を追加。

連結時に次のように置換した。

    $content = $content -replace '/docs/', '#'
    $content = $content -replace '\.md', ''

連結したMarkdownファイルをdocxファイルに変換する

これは、汎用文書変換ツールのPandocを使う。

用意するもの

  • Pandoc
  • Wordのテンプレートファイル:見出しなどに、必要な書式設定をしておく

変換コマンド

docxフォルダにあるconcat.mdをmanual.docxに変換する。

このときWord文書のテンプレートとしてtemplate_md2docx.docxを適用する。

$ pandoc -s .\docx\concat.md -o .\docx\manual.docx --reference-doc=.\docx\template_md2docx.docx

画像ファイルのパス

Pandocは、変換元の上位フォルダに画像があると読みにいかないみたい。

そこで、この変換コマンドを実行する前に、画像ファイルを下位フォルダにコピーする。で、変換後に削除した。

結果

これで、とりあえず複数のMarkdownファイルを連結して、Wordのdocxファイルに変換できた。

残課題

  • 目次の自動生成
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2