VSCodeでMarkdown記法の設計書をPuppeteerを使ってPDF出力する

# はじめに
VSCodeでMarkdown記法の設計書をPuppeteerを使ってPDF出力する！

タイトルそのままです。

Markdown記法によるドキュメント制作は、Gitでバージョン管理できたりAIによるサポートが効いたり（効きやすかったり）と、様々なメリットがあります。
元々はAPI設計書をメインにMarkdown記法を利用していましたが、drawioを使えばワイヤーフレームもAIに指示して記述できる事に気がつき、初めて画面設計書の作成に利用してみました。

Markdown Preview Enhancedをプレビュー表示しながらVSCodeで記述できるし、PuppeteerでPDF出力できるし、これでもう納品資料としても完璧だ！！

そう安易に考えていた時期が、私にもありました…

# Markdown Preview EnhancedでPDFプレビュー
Markdown Preview EnhancedではCSSでPDFプレビューの見た目を調整することができます。

コマンドパレット（win：[Ctrl]+[Shift]+[P]キー、mac：[Command]+[Shift]+[P]キー）で`Markdown Preview Enhanced: Customize CSS`を実行し、`style.less`を編集することで適用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186115/04a947b7-9831-4168-8b23-1aba0ad641e7.png)

```css
/* Please visit the URL below for more information: */
/*   https://shd101wyy.github.io/markdown-preview-enhanced/#/customize-css */

.markdown-preview.markdown-preview {
  // modify your style here
  // eg: background-color: blue;
  h1 {
    font-size: 20px;
  }
  h2 {
    font-size: 18px;
  }
  h3 {
    font-size: 16px;
  }
  h4, h5, h6 {
    font-size: 14px;
  }
  p {
    margin-left: 0.5em; /* 段落を一段下げる */
  }
  code {
    background-color: #f0f0f0; /* 背景色 */
    padding: 0.2em 0.4em; /* 内側の余白 */
  }
  img {
    display: block;
    margin-left: auto;
    margin-right: auto;
    max-width: 100%; /* 親要素の幅を超えないようにする */
    height: auto; /* アスペクト比を維持 */
  }
}
```

# PuppeteerでPDF出力
カスタムCSSで見出しや本文のスタイルを調整し、プレビュー表示が問題ないことを確認。
そしていざ`プレビュー上で右クリック > Export > Chrome(Puppeteer) > PDF`でPDF出力すると…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186115/888060ff-161a-4933-b10c-68777ee8c205.png)

なぜかスタイルが崩れまくってました・・・なぜなのか。

## 印刷時のスタイルを明示的に定義する必要がある

どうやら、Puppeteerは印刷時（`@media print`）のスタイルを適用しており、プレビュー表示で適用されるスタイルとは異なっている様でした。

`style.less`を書き換えてみます。

```css
/* Please visit the URL below for more information: */
/*   https://shd101wyy.github.io/markdown-preview-enhanced/#/customize-css */

.markdown-preview.markdown-preview {
  // modify your style here
  // eg: background-color: blue;
  h1 {
    font-size: 20px;
  }
  h2 {
    font-size: 18px;
  }
  h3 {
    font-size: 16px;
  }
  h4, h5, h6 {
    font-size: 14px;
  }
  p {
    margin-left: 0.5em; /* 段落を一段下げる */
  }
  code {
    background-color: #f0f0f0; /* 背景色 */
    padding: 0.2em 0.4em; /* 内側の余白 */
  }
  img {
    display: block;
    margin-left: auto;
    margin-right: auto;
    max-width: 100%; /* 親要素の幅を超えないようにする */
    height: auto; /* アスペクト比を維持 */
  }

  @media print {
    h1 {
      font-size: 20px;
    }
    h2 {
      font-size: 18px;
    }
    h3 {
      font-size: 16px;
    }
    h4, h5, h6 {
      font-size: 14px;
    }
    p {
      margin-left: 0.5em; /* 段落を一段下げる */
    }
    code {
      background-color: #f0f0f0; /* 背景色 */
      padding: 0.2em 0.4em; /* 内側の余白 */
    }
    img {
      display: block;
      margin-left: auto; /* 左右中央揃え */
      margin-right: auto; /* 左右中央揃え */
      max-width: 100%; /* 親要素の幅を超えないようにする */
      height: auto; /* アスペクト比を維持 */
    }
  }
}
```

出力したPDFにもスタイルが適用される様になりました。
しかし、なぜか背景色が白いまま・・・なぜなのか。

## 背景色の出力設定をする必要がある

Puppeteerではデフォルト設定で背景色が無視される様でした。

そこで、Markdownのファイル内でPuppeteerのPDF出力オプションを指定してやります。

```md
---
puppeteer:
  landscape: true
  format: "A4"
  printBackground: true, // 背景色を印刷する
---
```

無事に背景色も出力される様になりました。

しかし、毎回Markdown内に記述するのは手間ですし、ドキュメントの内容と直接関係のない記述をするのはいかがなものか…

と思ったらありました。

コマンドパレットで`Preferences: Open User Settings (JSON)`を実行し、`settings.json`に下記のオプションを追記することで適用できます。

```json
{
  "markdown-preview-enhanced.printBackground": true
}
```

# 終わりに
これで無事にドキュメントっぽいPDFの生成ができる様になりました。
MarkdownからのPDF出力に悩める誰かの助けになれば幸いです。

# 参考文献
https://shd101wyy.github.io/markdown-preview-enhanced/#/ja-jp/puppeteer