34
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

pandoc + markdownでいい感じの執筆環境を作る

Posted at

何番煎じ感はありますが、markdownを入力としていい感じの組版をしたいと思いました。

実現したこと

  • markdownをPDFに出力する
  • ディレクトリ横断して1ファイルに出力する
  • 任意のCSSを適用する
  • コードブロックに任意のキャプションを表示する(Qiitaで ```python:test.pyって書くようなやつ)
  • 任意の箇所で改ページする

markdownをPDFに出力する

PDFの出力にはpandocを利用しました

pandocのインストール

筆者の環境はMacなのでhomebrew経由でインストールしました


brew install pandoc

また、pandocでPDFを出力するためにwkhtmltopdfを追加でインストールしています

brew cask install wkhtmltopdf

これで準備は完了です

pandocでmarkdownをPDFに出力する

適当なマークダウンを用意します


これは00.mdのテストです

- foo
- bar

```python
import zen 

def __name__ == "=__main__":
    print('これはテストです')
```

コマンドを実行します
後にCSSを適用したいので、-tでhtmlを経由しているのがポイントです

pandoc src/00.md -f markdown -t html5 -o ./output.pdf

出力結果

スクリーンショット 2020-04-11 14.07.09.png

いい感じです

ディレクトリ横断して1ファイルに出力する

まとまった文章を書くときは章立てして書くことが多いと思います。そこで1ファイル1章を想定してそれぞれにファイルを分割し、けれども出力は1ファイルのような構成を考えてみます。

先程のファイルをコピーして、構成は以下のようにしてみました。

tree
.
└─── src
    ├── 00
    │   ├── 00.md
    │   └── 01.md
    └── 01
        └── 00.md

markdownで章の表現は#なので、先程のファイルの先頭行に#の行をそれぞれ追加します。


# テスト
これは00/00.mdのテストです

- foo
- bar

```python
import zen 

def __name__ == "=__main__":
    print('これはテストです')
```

pandocでは入力のファイルをglobで指定できるので以下のコマンドで1ファイルに出力できます

pandoc src/**/*.md -f markdown -t html5 -o ./output.pdf

さらに章番号を表示する-Nオプションを付与します

pandoc src/**/*.md -f markdown -t html5 -o ./output.pdf -N
スクリーンショット 2020-04-11 14.17.49.png

見た目の調整

これで最低限出力は出来ました。
ここからは見た目の調整や改ページの制御をします。

コードブロックの背景色を変更する

ハイライトのスタイルをtangoに変更すると背景色が変わります。オプションに--highlight-style=tangoを付与します。

pandoc src/**/*.md -f markdown -t html5 -o ./output.pdf -N --highlight-style=tango
スクリーンショット 2020-04-11 14.41.19.png

独自のCSSを当てる

よくmarkdownは表現力が弱いと言われますが、その点については独自にCSSを当てることで解消できます。

markdown内でhtmlタグを書いてしまえばclassを付与できるので、ここからはHTML + CSSの世界で整形できます。

ここでは適当にborderで囲っています

src/00/00.md
<div class="question">
以下のpythonコードの出力を答えよ
</div>
style.css
.question {
    border: 1px solid black;
    border-radius: 4px;
    padding: 4px;
}

コマンド実行時にCSSを指定します

pandoc src/**/*.md -f markdown -t html5 -c style.css -o ./output.pdf -N --highlight-style=tango
スクリーンショット 2020-04-11 14.50.32.png

コードブロックに任意のキャプションを表示する

Qiitaではコードブロックで
```md:src/00/00/md
のように書くとキャプションを付与できます。

スクリーンショット 2020-04-11 14.53.56.png

便利なのでこれを実現してみます。

pandocでは{} で様々なことができますが、その中の一つにhtmlに属性を付与する機能があります。

以下のように書いた場合、コードブロックの言語はpython、コードブロックのdata-caption属性に'test.py'を付与するようになります。


```{.python caption="test.py"}
import math 

def __name__ == "=__main__":
    print('これはテストです')
```

また、pandocではコードブロックの言語を指定したとき.sourceCodeクラスを付与します。
これを活用してCSSでdata-caption属性を表示すると以下のようになります。

style.css

.sourceCode:before{
    font-size: small;
	content:attr(data-caption);
    color: #eee;
    padding: 2px;
    background-color: #999;
}
スクリーンショット 2020-04-11 15.06.09.png

コードブロックに行数を表示する

これも {} で設定可能です。
.numberLines、startFromを活用します。


``` { .python .numberLines caption="test.py"}
import math 

def __name__ == "=__main__":
    print('これはテストです')
```

4行目だけ表示します

``` { .python .numberLines startFrom='4'}
    print('これはテストです')
```
スクリーンショット 2020-04-11 15.12.15.png

任意の箇所で改ページする

これもCSSで表現可能です。

空のdivタグを任意の改ページしたい箇所に挿入します

<div class="page-break"></div>
style.css
.page-break {
	page-break-before:always;
}

fontを変える

繰り返しですがCSSで表現可能な値は調整可能です

style.css
body {
    font-family: -apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Helvetica Neue", HelveticaNeue, "游ゴシック体", YuGothic, "游ゴシック Medium", "Yu Gothic Medium", "游ゴシック", "Yu Gothic", Verdana, "メイリオ", Meiryo, sans-serif;
}
スクリーンショット 2020-04-14 12.59.58.png

所感

ややCSSでのマークアップ知識は必要ですが、CSSを適用できると技術書の執筆だけに留まらないのかと思いました(e.g. 学校のテスト問題など)

ちょっと触っただけでもpandocの多機能さ = オプションの多いことがわかりました。やりたいことがあるときはまずオプションを漁ってみるのがいいと思います。

参考

多様なフォーマットに対応!ドキュメント変換ツールPandocを知ろう - Qiita
Pandoc ユーザーズガイド 日本語版 - Japanese Pandoc User's Association
Inner Journeys: PandocのHTML出力でGFMとカスタムテンプレートを使う
Pandoc Markdown のあまり知られていない書法 - Chienomi
【 content:attr() 】CSSでタグのdata属性やtitle属性を取得して表示する | 8bit モノづくりブログ|Web制作、Webサービスに関するコラム|東京都渋谷区のWeb制作会社 株式会社8bit
VScodeのMarkdownからPDF変換時に改ページを挿入 - Qiita
Markdownをgithub-markdown.cssを充てつつwkhtmltopdfでpdfに変換 - Qiita
markdown + pandoc で、1問1答の小テストプリントを作る - adbird(広告鳥) 備忘録

34
32
1

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
34
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?