命名って難しい

変数、関数、クラスなどなど実装より命名に毎回悩むタイプの人間による技術についてのメモ。

どうにかドキュメントをmarkdownで書かせてhtmlに変換したい

ドキュメントはOfficeのExcelやWordの弊社ですが、やはりバージョン管理システムを利用していると変更点を知りたいことがあるので、markdownで書いて欲しいと思っています。

しかし、markdown自体も社内では認知されておらず、また閲覧することもままならないので、htmlに変換して見せようと思いました。ただし、他の作業者(markdown知らない)を考慮し、環境設定も考えてみます。

環境

やりたいこと

環境設定スクリプト

実現したい環境

pandocでmarkdownを変換できる環境

pandoc…の前にwinget

「ググって普通にインストールしてくれ」で済めばいいんですが、野良の変なインストーラーをつかんでセキュリティインシデントになっても困るので方法を統一する上で winget を利用します。

learn.microsoft.com

これはMicrosoft Storeで配布されているので、誰でも間違いなくインストールできます。 しかしこれもストア内検索で変なアプリを入れてしまうリスクを避けるために環境設定スクリプトに含めちゃいます。

# ストアのアプリ インストーラー(winget)のページを開くからインストールしてね、とスクリプト上でメッセージを出す
[System.Diagnostics.Process]::Start('ms-windows-store://pdp/?productId=9NBLGGH4NNS1')

何度も表示しないよう、pandocがインストール済か、Get-Commandで確認します。

それを加味すると以下のようになります。

if (-not (Get-Command winget -ErrorAction Ignore)) {
    # ストアのアプリ インストーラー(winget)のページを開くからインストールしてね、とスクリプト上でメッセージを出す
    [System.Diagnostics.Process]::Start('ms-windows-store://pdp/?productId=9NBLGGH4NNS1')
    pause
    exit
}

これでwingetのインストール部分は完成

pandoc

wingetがインストールできたので次はpandocのインストールです。 インストール済みである場合を考慮して以下のようにします。

Get-Command でチェックしてインストールする方法

if (-not (Get-Command pandoc -ErrorAction Ignore)) {
    winget install JohnMacFarlane.Pandoc
}

wingetを生かしてwinget list pandocでも確認できます。 その場合は $LASTEXITCODE0の時がインストール済です。

pandoc用のテンプレート導入

html出力しただけではドキュメント読者には辛いと思うのでシンプルできれいなテンプレートを利用します。

ryangrose/easy-pandoc-templates github.com

$template = '.\.pandoc_template.html'
Invoke-WebRequest `
    -Uri https://raw.githubusercontent.com/ryangrose/easy-pandoc-templates/master/html/elegant_bootstrap_menu.html `
    -OutFile "$template"

まとめ(setup_documentation_env.ps1)

以上の内容をまとめて以下のように実装しました。

if (-not (Get-Command winget -ErrorAction Ignore)) {
    # ストアのアプリ インストーラー(winget)のページを開くからインストールしてね、とバッチ上でメッセージを出す
    [System.Diagnostics.Process]::Start('ms-windows-store://pdp/?productId=9NBLGGH4NNS1')
    Pause
    # 一旦終了してwingetをインストールしてもらう
    exit
}


if (-not (Get-Command pandoc -ErrorAction Ignore)) {
    winget install JohnMacFarlane.Pandoc
}

# pandocのテンプレートをローカルにダウンロードする。
$template = '.\.pandoc_template.html'
Invoke-WebRequest `
    -Uri https://raw.githubusercontent.com/ryangrose/easy-pandoc-templates/master/html/elegant_bootstrap_menu.html `
    -OutFile "$template"

html出力スクリプト

ここまでで環境設定が完了したのでhtmlに出力するスクリプトを実装します。

ベースとなるフォルダの中に documents というフォルダがあることを前提として、そのフォルダ内でmdファイルをhtmlファイルに変換していくという処理のスクリプトです。

Set-Location $PSScriptRoot

Get-ChildItem -Path .\documents -Filter *.md | ForEach-Object {
    $command = "pandoc -s --table-of-contents --template=.pandoc_template.html $($_.FullName) -o $($_.FullName -replace '\.md$','.html')"
    Invoke-Expression $command
}

これで出力するとブラウザで以下のように表示されるhtmlファイルが生成されます。

githubにサンプルを置きました。

github.com