ジンジャー研究室

長めのつぶやき。難しいことは書きません。

Markdown形式で書いた記事やレポートをPDF形式で配布する

あまりまとまってる記事がないので書いた。

やりたいこと

Markdownでさらっと書いた記事を社内に共有したい。 しかしMarkdownだと色々問題がある。

  • 標準的なビュアがない
  • PC環境によって見え方が変わる
  • 画像などを含めるためにZIPなどで共有する必要があり読む側が面倒

Gistでもいいが、GistだとprivateにしてもURLがバレたら普通に外から見えるので実質public。

というわけで、PDF1ファイルにまとめたい。 スタイルを含んだHTML1ファイルでも良さそうだが、フォントがOSによって変わったり、Webフォントだとしてもオフライン時に崩れる問題があるので、やはりPDFが理想。

Markdownの下準備

PDFに変換する前にやっておくと良いかもしれないこと。

目次の自動生成

ある程度長い場合は目次が作りたくなる。 Node.js環境ならdoctocというツールが使える。

改ページの制御

PDF出力または印刷時にどうしても改ページしたい場所があれば、Markdown中に次のコードを入れる。

<div style="page-break-before:always"></div>

あるいはclass指定してCSSで制御しても良い。

PandocによるHTMLの出力

Pandocを使うとMarkdownからHTMLやPDFが作れる。 ただし日本語の場合はPDFを作るのにTeXが必要。そのためだけにTeXをインストールしたくないので、HTMLを出力してChromeの印刷機能でPDFを出力することにする。

シンタックスハイライトを有効にする

Pandocのオプションで有効にする言語を指定。複数の場合はカンマ区切り。

--indented-code-classes="haskell,css"

Markdownで次のように言語を指定します。

 ```haskell
 qsort [] = []
 ```

CSSをカスタマイズする

Pandocで何も指定しないとスタイルが微妙だったりするので、CSSを指定するようにする。ちなみにHTMLには埋め込まれない模様。

pandoc article.md -s -o output.html -c style.css

GitHub風にしたい場合はgithub.cssが使える。あとはBootstrapベースで作られたこちらのCSSもなかなか良い。

必要に合わせてfont-familyなどを変更する。以下は追記するCSSの例。

body {
  padding: 10px 10%;
  font-family: 'Noto Sans Japanese', "Hiragino Kaku Gothic Pro", meiryo, "Open Sans", sans-serif;
}
table {
  width: 100% !important;
}
col:first-child {
  width: 2%;
}
img {
  max-width: 100%;
}

画像幅をカスタマイズする

Markdownでは画像の大きさが指定できないので、CSSで一つずつ書く。

img[src="foo.png"] {
  width: 75%;
}

特定のテーブルのスタイルをカスタマイズする

CSSで指定するために本当はテーブルにIDを振りたいが、そういう機能がないので隣接セレクタでなんとかする。

<div id="table-foo"></div>
|名前|値段|
|:--|:--|
|みかん|50円|
|りんご|100円|
#table-foo + table {
  width: 30% !important;
}

Webフォントを使う

Windowsだとフォントが微妙だったりするので、Webフォントを使う。上のCSSで指定している'Noto Sans Japanese'はHTMLに次のコードを加えると使えるようになる。

<style>
  @import url(http://fonts.googleapis.com/earlyaccess/notosansjapanese.css);
</style>

HTMLに直接書くと次の更新時に上書きされてしまうので、HTMLのヘッダにコードを含めるオプションを利用する。

-H import-font.css

ChromeによるPDF出力

Chromeブラウザで印刷画面を出して(Ctrl+P)PDFで保存。他のブラウザは使っていないので知らない。

f:id:jinjor:20160204151733p:plain

以上。あとはこの一連のプロセスをスクリプト化したら快適になりそう。