最近、Markdownからpdfを作る機会がありました。
pdf化を都度行うのは手間だったため、何か良い方法がないかを探したところ、 Markdown > Re:VIEW > pdf
という経路でpdfを作成できそうでした。
ただ、手動でpdfを生成するのが手間だったため、GitLab CIを使って、push後にMarkdownをtextlintしてからpdf化するCI環境を作ってみました。
目次
環境
項目 | 内容 |
---|---|
CI環境 | GitLab.comのCI |
Lintツール | textlint |
Lint辞書 | 自作 |
Markdownからpdf化の方法 | Markdown > Re:VIEW > pdf |
MarkdownからRe:VIEWへの変換 | md2review |
Re:VIEWからpdfの変換 | review-pdfmaker |
pdfのレイアウト調整 | Re:VIEWなどに詳しくないため、今回は行わない |
pdf化する対象のMarkdownは target.md
です。それ以外のファイルについては後述します。
$ tree . └── docs ├── catalog.yml ├── config.yml ├── prh.yml ├── sty │ ├── README.md │ ├── gentombow.sty │ ├── jsbook.cls │ ├── jumoline.sty │ ├── plistings.sty │ ├── review-base.sty │ ├── review-custom.sty │ ├── review-jsbook.cls │ ├── review-style.sty │ ├── reviewmacro.sty │ └── techbooster-doujin-base.sty ├── style-web.css ├── style-web.scss ├── style.css ├── style.scss └── target.md
また、対象のMarkdownファイル target.md
は以下のような感じです。
(Pythonコードについては、実際はトリプルバッククォートで囲みましたが、はてなブログに貼り付ける都合上、トリプルシングルクォートにしてあります)
# タイトル Pythonコードを書きます。 ''' print('Hello world') ''' ## りんごの時期 以下の表を参照のこと。 |項目|時期| |---|---| |夏あかり|お盆過ぎ| |シナノドルチェ|9月中頃| |シナノゴールド|10月過ぎ|
GitLab CIの設定ファイル .gitlab-ci.yml の作成
GitLabでCIを動かすために .gitlab-ci.yml
が必要なので作成します。
今回は、以下のようなPipelineを作成します。
No | 対象ブランチ | 条件 | ジョブの内容 |
---|---|---|---|
1 | 全ブランチ | GitLabへpush時 | 対象のMarkdownにtextlintを実行 |
2 | 指定ブランチ | No.1成功時 | Markdownをpdf化 |
ステージを定義
ジョブを順番に実行するため、ステージを2つ定義します (lint
と build
)。
stages: - lint - build
ジョブを定義
2つのジョブ markdown_lint
と pdf_build
を定義します。
また、ジョブの stage
にて、各ジョブがどのステージで動作するかを指定します。
markdown_lint: stage: lint pdf_build: stage: build
ジョブ「対象のMarkdownにtextlintを実行」の詳細を定義
ジョブ markdown_lint
は、対象のMarkdownにtextlintを実行します。
以下を参考に、今回は textlint
と textlint-rule-prh
を使うことにします。
textlint + prhで表記ゆれを検出する | Web Scratch
textlintはNode.jsがあれば動作するようなので、Dockerの公式リポジトリから一番軽そうなイメージ node:11.12.0-alpine
を使います。
before_script
でtextlintのインストールを行い、 script
でtextlintを実行します。
ジョブの全体は以下の通りです。
markdown_lint: image: node:11.12.0-alpine stage: lint before_script: - npm install -g textlint textlint-rule-prh script: - cd docs - textlint target.md
ジョブ「Markdownをpdf化する」の詳細を定義
ジョブ pdf_build
は、Markdownファイルをpdf化します。
今回、Markdown > Re:VIEW > pdfの変換では、以下のツールを使います。
Dockerイメージは、必要なファイルがすべて含まれている vvakame/review
を使います。ありがとうございます。
https://github.com/vvakame/docker-review
あとは、 before_script
にて必要なものをインストールし、 script
にて変換を行います。
pdf_build: image: vvakame/review stage: build before_script: - apt-get update -y - apt-get -y install build-essential ruby-dev - gem install md2review script: - cd docs - md2review target.md > target.re - review-pdfmaker config.yml
なお、変換後のpdfをダウンロードできるようにするため、 artifacts
を定義します。
今回は、中間でできる target.re
ファイルやpdfなど、Git管理外ファイルをダウンロードするため、 untracked: true
とします。
artifacts: untracked: true
また、pdfをビルドするブランチを master
と feature/*
に制限するため、 only
も定義しておきます。
only: - master - /^feature\/.*$/
設定ファイル .gitlab-ci.yml
の全体は以下の通りです。
stages: - lint - build markdown_lint: image: node:11.12.0-alpine stage: lint before_script: - npm install -g textlint textlint-rule-prh script: - cd docs - textlint target.md pdf_build: image: vvakame/review stage: build before_script: - apt-get update -y - apt-get -y install build-essential ruby-dev - gem install md2review script: - cd docs - md2review target.md > target.re - review-pdfmaker config.yml artifacts: untracked: true only: - master - /^feature\/.*$/
textlint向けの定義
以下を参考に、textlint向けの定義を行います。
textlint + prhで表記ゆれを検出する | Web Scratch
今回は、 doc
ディレクトリの中に、 prh.yml
と textlintrc
を作成します。
prh.yml
まずは prh.yml
に、textlintでチェックする内容を記載します。
今回は「Python」という単語の表記ゆれはエラーとなるように設定します。
version: 1 rules: - expected: Python specs: - from: python to: Python - from: PYTHON to: Python
.textlintrc
textlint実行時に prh.yml
を参照するよう設定します。
{ "rules": { "prh": { "rulePaths": [ "./prh.yml" ] } } }
review-pdfmaker向けの設定
review-pdfmaker向けの設定については、以下のリポジトリを参考にしました。また、一部ファイルはそのまま利用させていただきました。ありがとうございました。
https://github.com/TechBooster/ReVIEW-Template
config.ymlの設定
review-pdfmaker
を実行する時の定義ファイル config.yml
を doc
ディレクトリの中に作成します。
ReVIEW-Templateを元に、以下の内容を記載します。
# この設定ファイルでサポートするRe:VIEWのバージョン番号。 # major versionが違うときにはエラーを出す。 review_version: 3.0 # ブック名(ファイル名になるもの。ASCII範囲の文字を使用) bookname: my_sample_book # 記述言語。省略した場合はja language: ja # 書名 booktitle: {name: "サンプル本", file-as: "sample book"} # 著者名。「, 」で区切って複数指定できる aut: [{name: "thinkAmi", file-as: "thinkAmi"}] # 以下はオプション # a-edt, edt: 編集者 edt: ["my editor"] # a-pbl, pbl: 出版社(発行所) pbl: thinkami_pub. # 刊行日(省略した場合は実行時の日付) date: 2019-3-24 # 発行年月。YYYY-MM-DD形式による配列指定。省略した場合はdateを使用する # 複数指定する場合は次のように記述する # [["初版第1刷の日付", "初版第2刷の日付"], ["第2版第1刷の日付"]] # 日付の後ろを空白文字で区切り、任意の文字列を置くことも可能。 history: [["2019-3-24 v0.0.1"]] # 権利表記(配列で複数指定可) # rights: (C) 2016 Re:VIEW Developers rights: (C) 2019 thinkAmi # デバッグフラグ。nullでないときには一時ファイルをカレントディレクトリに作成し、削除もしない debug: null # HTMLファイルの拡張子(省略した場合はhtml) htmlext: html # # CSSファイル(配列で複数指定可、yamlファイルおよびRe:VIEWファイルを置いたディレクトリにあること) stylesheet: ["style.css"] # ePUBのバージョン (2か3) epubversion: 3 # # HTMLのバージョン (4か5。epubversionを3にしたときには5にする) htmlversion: 5 # 目次として抽出する見出しレベル toclevel: 3 # 採番の設定。採番させたくない見出しには「==[nonum]」のようにnonum指定をする # # 本文でセクション番号を表示する見出しレベル secnolevel: 3 # 本文中に目次ページを作成するか。省略した場合はnull (作成しない) toc: true # 表紙の後に大扉ページを作成するか。省略した場合はnull (作成しない) titlepage: true # 奥付を作成するか。デフォルトでは作成されない。trueを指定するとデフォルトの奥付、ファイル名を指定するとそれがcolophon.htmlとしてコピーされる colophon: true # EPUBにおけるページ送りの送り方向、page-progression-directionの値("ltr"|"rtl"|"default") direction: "ltr" epubmaker: # HTMLファイルの拡張子 htmlext: xhtml stylesheet: ["style.css","epub_style.css"] # LaTeX用のスタイルファイル(styディレクトリ以下に置くこと) texstyle: ["reviewmacro"] # B5の設定(10pt 40文字×35行) - 紙版 texdocumentclass: ["review-jsbook", "media=print,paper=b5,serial_pagination=true,hiddenfolio=nikko-pc,openany,fontsize=10pt,baselineskip=15.4pt,line_length=40zw,number_of_lines=35,head_space=30mm,headsep=10mm,headheight=5mm,footskip=10mm"] pdfmaker: # 奥付を作成するか。trueを指定するとデフォルトの奥付、ファイル名を指定するとそれがcolophon.htmlとしてコピーされる colophon: true webmaker: stylesheet: ["style.css","style-web.css"]
pdf化するコンテンツの設定 (catalog.yml)
pdfに含まれるコンテンツの設定を行います。
本文部分のRe:VIEWファイルは、 target.md
が変換された target.re
になります。そのため、 target.re
を CHAPS
に指定します。
PREDEF: CHAPS: - target.re APPENDIX: POSTDEF:
デザインまわりのファイルのコピー
今回デザインまわりは何も修正しないため、リポジトリ TechBooster/ReVIEW-Template
のものをそのままコピーしました。
コピーするのは以下です。
以上で準備が終わりました。
動作確認
masterブランチ
今までの作業を master
ブランチにコミットし、GitLabにpushします。
すると、以下の画像のように、Lintとpdfの生成ができました。
右側にあるダウンロードボタンを押すことで、Re:VIEWとpdfのファイルがzip化されたものがダウンロードできます。
featureブランチ
次に、Lintエラーが出るように以下を追加した target.md
をfeatureブランチにcommitします。
- python - PYTHON
GitLabにpushしてCIを確認すると、Lintチェックエラーになりました。
また、後続のpdf作成ジョブは実行されていませんでした。
lint-onlyブランチ
最後に、Lintエラーが出るように以下を追加した target.md
を lint-only
ブランチにcommitします。
- Lintだけします - python
GitLabにpushしてCIを確認すると、Lintチェックエラーになりました。
また、今までと異なり、後続ジョブ pdf_build
がありません。
以上で、GitLab CI + docker-reviewを使って、Markdownをtextlintしてからpdf化するCI環境ができました。