Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/content/blog-metas/2024-12-21-mermaid-to-pdf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"postDate": "2024-12-22T08:18:17.106Z"
}
94 changes: 94 additions & 0 deletions src/content/blogs/2024-12-21-Mermaid-to-pdf.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
title: Mermaidのグラフをpdfにする
description: Mermaidで作成した図表のみのpdfを作成する。
category: tech
author: TaPet
tags: [advent-calendar, markdown]
---

import {Image} from 'astro:assets';
import mdToPdf from './2024-12-21-Mermaid-to-pdf/md-to-pdf.png';
import Inkscape from '2024-12-21-Mermaid-to-pdf/Inkscape.png';
import rsvgConvert from '2024-12-21-Mermaid-to-pdf/rsvg-convert.png';
import Cairosvg from '2024-12-21-Mermaid-to-pdf/Cairosvg.png';
import headless1 from '2024-12-21-Mermaid-to-pdf/sample_1.png';
import headless2 from '2024-12-21-Mermaid-to-pdf/sample_2.png';
import svg from '2024-12-21-Mermaid-to-pdf/sample.svg'


この記事は[OUCC Advent Calendar 2024](https://adventar.org/calendars/10655)の21日目の記事です。

## 記事作成後の気づき
[SVGからPDFへの変換はHeadless Chromeでやろう(と思ったけどやっぱりrsvg-convertでやろう)](https://qiita.com/s417-lama/items/747be70c35204d4e1b39#headless-chrome)の最後にも書いてありましたが、Headless Chromeを使うと、ラスタ画像になっていました。~~(ちゃんと読んでないのが悪い)~~ これでは、この記事の目的は達成できていません。(ラスター画像なら、[mermaid-cli](https://github.com/mermaid-js/mermaid-cli)で作成できる。)
→svgファイルをいじって、ほかの方法で文字が表示されるようにするしかない?

ほかの方法で変換できれば記事を更新します。

---

試した手法とその結果も載せています。
最終的な方法だけ見たい方は、[結論](#結論)を見てください。

## やりたかったこと
学校の課題で、 LaTeXでレポートを書く必要がありました。
その際、状態遷移図を乗せる必要があったので、Mermaidで簡単に作ってしまおうと思いましたが、作った画像をどう表示させようか悩みました。
LaTeXにsvgを張るのは面倒 (LaTeXのことをよくわかってない) ので、pdfにして表示しようと思いましたが、うまく変換できませんでした。
~~なお、ベクター画像でなければならない理由はない。やりたかっただけ~~

## 試した方法
pdfは載せられないので、pngに変換して載せます。
### Markdown内に書いて、pdfで出力
いくつかの変換方法を試しましたが、文書として出力されるため、画像のみのpdfは出力できませんでした。
pdf内にグラフが小さく表示されてしまいます。

<Image src={mdToPdf} alt="" width="600px" style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333;"/>

### Mermaid → svg → pdf
[mermaid-cli](https://github.com/mermaid-js/mermaid-cli) というMermaidをsvg/png/pdfに変換できる、cliアプリケーションが見つかりました。これで、Mermaidをsvgに変換し、それをpdfに変換する方法を試しました。
#### Inkscape
Inkscapeで、`inkscape --export-type="pdf" sample.svg`などとして、pdfに変換しようと思いましたが、うまくいかず、黒塗りの画像が出てきてしまいました。mermaid-cliで生成されるsvgには、Inkscapeが想定していない情報も書いてあるようで、そのために処理がうまくいかないようでした。

<Image src={Inkscape} alt="" width="600px" style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333;"/>

#### 別の方法
[SVGからPDFへの変換はHeadless Chromeでやろう(と思ったけどやっぱりrsvg-convertでやろう)](https://qiita.com/s417-lama/items/747be70c35204d4e1b39#headless-chrome)を見つけ、そこで紹介されていた、rsvg-convert、Cairosvgは、文字が描画されませんでした。

<ul style="display: flex;">
<il><figure><Image src={rsvgConvert} alt="" width="300px" style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333;"/><figcaption>rsvg-convert</figcaption></figure></il>
<il><figure><Image src={Cairosvg} alt="" width="300px" style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333;"/><figcaption>Cairosvg</figcaption></figure></il>
</ul>

Headless Chromeでは、ページいっぱいの大きさのグラフが載ったpdfを作成できました。
<ul style="display: flex;">
<il><figure><Image src={headless1} alt="" width="300px" style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333;"/><figcaption>1ページ目</figcaption></figure></il>
<il><figure><Image src={headless2} alt="" width="300px" style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333;"/><figcaption>2ページ目</figcaption></figure></il>
</ul>

## 結論
Mermaidのみを、ファイルに書き、[mermaid-cli](https://github.com/mermaid-js/mermaid-cli)で、svgに変換し、[SVGからPDFへの変換はHeadless Chromeでやろう(と思ったけどやっぱりrsvg-convertでやろう)](https://qiita.com/s417-lama/items/747be70c35204d4e1b39#headless-chrome)で紹介されている、[svg2pdf.bash](https://gist.github.com/s417-lama/84bf66de1096c4587e8187092fb41684)を使って、pdfに変換する。
ただし、このpdfには、謎の2ページ目が存在するので、1ページ目のみを使用する。(1ページ目のみを参照するなり、別ファイルに1ページ目のみを書き出すなりしてください。)

<details>
<summary>サンプル</summary>

Mermaidファイルの記述

```sample.mmd
graph TD
a-->b
a-->c
b-->d
c-->e
d-->e
```

Mermaid
<Image src={svg} alt=""/>

PDF
<ul style="display: flex;">
<il><figure><Image src={headless1} alt="" width="300px" style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333;"/><figcaption>1ページ目</figcaption></figure></il>
<il><figure><Image src={headless2} alt="" width="300px" style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333;"/><figcaption>2ページ目</figcaption></figure></il>
</ul>

</details>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/content/blogs/2024-12-21-Mermaid-to-pdf/sample.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.