MarkdownをPDFで出力する方法

## はじめに
MarkdownをPDFに変換するには､`puppeteer`というソフトが必要です｡
puppeteerは､**HTMLをPDFに変換できる**ツールです｡

ちなみに､「**Markdownをhtmlで出力する方法**」を知りたい方は､[こちら](https://l.pg1x.com/jGp8)を確認してください｡

## 準備
`puppeteer`と`markdown-it-plugin`をインストールします｡
```bash:puppeteerをインストール
$ npm install markdown-it
$ npm install puppeteer
```

以下のようなフォルダ構造となります｡
```bash:
$ tree -L 1
.
├── convert.js
├── input.md
├── node_modules
├── package-lock.json
└── package.json

1 directory, 4 files
```

## 実行ファイル
以下を`convert.js`にコピペしてください｡

```javascript:convert.js
'use strict';

const 
    { promisify } = require('util'),
    path = require('path'),
    fs = require('fs'),
    readFile = promisify(fs.readFile),
    md = require('markdown-it')(),
    puppeteer = require("puppeteer");



async function main(input,output) {
    try {
        const
            markdown = await readFile(input, 'utf-8'),
            html = md.render(markdown),
            browser = await puppeteer.launch({ headless: "new" }),
            page = await browser.newPage();
            
        // Puppeteerを使用してHTMLをPDFに変換
        await page.setContent(html, {// HTMLコンテンツをページに設定
            waitUntil: 'networkidle0'
        }); 
        await page.pdf({ // puppeteerのPDF出力設定
            path: output,
            format: 'A4',
            displayHeaderFooter: true,
            margin: {
                top: '2cm',
                right: '2cm',
                bottom: '2cm',
                left: '2cm',
            },
            headerTemplate:`<div style="font-size: 9px; margin-left: 1cm;"> <span class='title'></span></div> <div style="font-size: 9px; margin-left: auto; margin-right: 1cm; "> <span class='date'></span></div>`,
            footerTemplate: `<div style="font-size: 8px; margin: 0 auto;"> <span class='pageNumber'></span> / <span class='totalPages'></span></div>`,
            printBackground: true,
            preferCSSPageSize: true,
            scale: 0.8,
        });          
        await browser.close();
        console.log('PDF created !');
    } catch (e) {
        console.error('file error', e);
    } 
}

const
    args = process.argv.slice(2),
    input = path.resolve(__dirname, args[0]),
    output = path.resolve(__dirname, args[1]);


main(input, output);
```

## PDFに変換する
input.mdは以下のようになっているとします｡
```md:input.md
# マイプロフィール

## 基本情報
- 名前: **yusu79**
- 性別: 男性

## スキルセット
- プログラミング言語:
  - JavaScript
- フレームワーク:
  - Node.js
- データベース:
  - MySQL

## 興味・趣味
- 機械学習
- 自然言語処理
- ゲーム開発

以上が私のプロフィールです。よろしくお願いします！
```
この状態で､`node convert.js input.md output.pdf`とすれば､同じフォルダ内にoutput.pdfが生成されます｡
```bash:MarkdownをPDFに変換して出力
$ node convert.js input.md output.pdf
PDF created !
```

![MarkdownをPDFで出力する方法.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395294/5deec844-3853-7806-2e5a-b588f983d1ca.png)

## puppeteerとは？
Puppeteerは、Googleによって開発されたオープンソースのヘッドレスブラウザ制御ツールです。

ヘッドレスブラウザとは、**GUIを持たずにバックグラウンドで動作するブラウザ**のことを指します。Puppeteerは、ChromeまたはChromiumブラウザを制御し、自動化されたタスクやWebスクレイピング、テストなどの目的で使用することができます。

`puppeteer.pdf`は、Puppeteerの機能の1つであり、ChromeまたはChromiumブラウザを使用してWebページをPDF形式でエクスポートする事が出来ます｡

### puppeteerの設定
`await page.pdf({オプション})`とすれば､PDFが出力されます｡
その際に､以下のような設定をする事が出来ます｡

- `path`: PDFファイルの保存先のパスを指定します。
- `format`: PDFの用紙サイズを指定します。
- `displayHeaderFooter: true`: ヘッダーとフッターを表示するかどうかを指定します。
- `margin: {}`: PDFページの余白を設定します。
- `headerTemplate`: ヘッダーのHTMLテンプレートを指定します｡
- `footerTemplate`: フッターのHTMLテンプレートを指定します。
- `printBackground: true`: 背景グラフィックスを印刷するかどうかを指定します。
- `preferCSSPageSize: true`: CSSのページサイズを優先するかどうかを指定します。
- `scale`: ページのスケールを設定します。




## GitHub
- [markdown-it/markdown-it: Markdown parser, done right. 100% CommonMark support, extensions, syntax plugins & high speed](https://l.pg1x.com/G6nd)
- [puppeteer/puppeteer: Node.js API for Chrome](https://l.pg1x.com/XB8m)