Markdown から HTML と PDF を作る
講義記録や業務文書を書くにあたって,ひとつのファイルから HTML と PDF をそれなりの見た目で作れるように VSCode の Markdown PDF を用いてテンプレートを作った。 これをまとめる。
背景
年度替わりにあたって,長らく情報の授業を持っていただいていた同僚が異動なさった。それに伴い,この1年は私が情報の授業を4単位分ほど担当することとなった。
情報を持つのは6年ぶりであり,カリキュラムも変わっている。 何より,生徒が1人ずつ端末を持っている。 そこで,復習しやすいようにウェブサイト上に講義記録を残すことにした。 少しでも手間が小さくなるよう,原稿は Markdown で書き VSCode によって HTML を作る。また,一部を印刷して配りたくなるかもしれないので,そのまま PDF にもできるようにしたい。
解決
Markdown PDF の導入
Markdown から HTML と PDF を作るには Markdown PDF を用いる。
VSCode を導入していれば,[拡張機能]から markdown pdf と検索してすぐに現れる。似た名前のものがいくつかあるが,ダウンロード数や評価を見ればよい。作者は yzane 氏である。
その他の VSCode 環境
Markdown の入力支援として Markdown All in One をインストールしている。
- https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one
- (Yu Zhang)
- Markdown All in One
- Extensions for Visual Studio Code
- 参照 2025-05-06
スニペットの入力支援として Easy Snippet をインストールしている。
- https://marketplace.visualstudio.com/items?itemName=inu1255.easy-snippet
- (inu1255)
- Easy Snippet
- Extensions for Visual Studio Code
- 参照 2025-05-06
これらは導入しなくとも差しつかえないが,一部の記述はこれらを踏まえている。
VSCode における Markdown PDF の設定
Footer Template はそのまま用いることとした。
Header Template は修正しやすいよう,style='display: none; のみを加えて非表示とした。
<div style="font-size: 9px; margin-left: 1cm;"> <span class='title' style='display: none;'></span></div> <div style="font-size: 9px; margin-left: auto; margin-right: 1cm; display: none;">%%ISO-DATE%%</div>
VSCode における Markdown のスニペット
改行位置の指定
印刷するにあたっての改行位置を指定するため,次のようにした。
// @prefix pagebreak-pdf
// @description
<div style="page-break-before:always"></div>
スタイルシート
ここで,CSS を読み込む機能があるようだが,校内のファイル共有システムなどを踏まえ,オフライン環境でも扱えるようスタイルシートはファイルに直に書き込むこととした。いずれ見映えを変えたくなったときに使いまわしにくいことには気をつけたい。
- 画面表示としても PDF としても見やすく,配置が大きく変わらないよう,間を取ってデザインした。
- PDF は A4 用紙を想定している。
max-width: 600px;とpadding: 0 26px;を指定している。- 白黒印刷でも見やすいようデザインした。
emは圏点としている。emの意味からいえば,日本語では圏点がふさわしいだろう。<!-- -->を取り除くことで MathJax を使えるようにしている。
// @prefix @css
// @description
<style>
/* CSS for Markdown to html/PDF 20251116 */
html, body {
font-family: "BIZ UDMincho", serif;
font-size: 15px;
padding: 0 26px;
line-height: var(--markdown-line-height, 22px);
word-wrap: break-word;
text-align: justify;
overflow-wrap: break-word;
hanging-punctuation: last allow-end;
margin-left: auto;
margin-right: auto;
}
body {
line-height: 1.6;
max-width: 600px;
}
h1, h2, h3, h4, h5, h6, p, ol, ul, pre {
margin-top: 0;
}
h1, h2, h3, h4, h5, h6 {
font-family: "BIZ UDGothic", sans-serif;
font-weight: 500;
margin-top: 24px;
margin-bottom: 16px;
line-height: 1.25;
}
h1 {
font-size: 1.75em;
font-weight: 700;
margin-top: 0;
padding-bottom: 0.1em;
border-color: rgba(0, 0, 0, 0.35);
border-bottom-width: 3px;
border-bottom-style: double;
}
h2 {
font-size: 1.35em;
font-weight: 700;
padding-bottom: 0.1em;
border-color: rgba(0, 0, 0, 0.35);
border-bottom-width: 1px;
border-bottom-style: solid;
}
h3 {
font-weight: 700;
font-size: 1.25em;
}
h4 {
font-size: 1.1em;
}
blockquote {
margin: 0;
padding: 0px 16px 0 10px;
border-left-width: 5px;
border-left-style: double;
background: transparent;
border-color: rgba(0, 0, 0, 0.35);
}
ul, ol {
margin-top: 0;
padding-left: 2em;
}
ul li:last-child, ul li li:last-child, ul li li li:last-child {
margin-bottom: 0.25em;
}
ul li li, ul li li li, ul li ul li, ul li ul li ul li {
margin-bottom: 0;
}
p {
text-indent: 1em;
margin-bottom: 1em;
}
p:has(img) {
text-indent: 0em;
margin-bottom: 1em;
}
ul img {
padding-top: 3px;
vertical-align: top;
}
ol img {
padding-top: 3px;
vertical-align: top;
}
:not(pre):not(.hljs) > code {
color: #FA7A00; /* #F6AA00; #FF4B00; */
padding: 1px 6px;
/* background-color: #f8f8f8; */
border: 1px solid #cccccc;
border-radius: 3px;
}
code {
color: #FA7A00;
font-family: Consolas, Menlo, Meiryo, "Hiragino Kaku Gothic ProN", monospace;
font-size: 1em;
}
pre {
color: #FA7A00;
background-color: transparent;
border: 1px solid #cccccc;
border-radius: 3px;
overflow-x: auto;
white-space: pre-wrap;
overflow-wrap: break-word;
}
.hljs {
display: block;
overflow-x: auto;
color: #FA7A00;
padding: 0.5em;
}
pre:not(.hljs), pre.hljs code > div {
padding: 1px 16px;
border-radius: 3px;
overflow: auto;
}
a {
color: #005AFF; /* #4DC4FF */
text-decoration: underline;
}
a:visited {
color: #003CAA; /* #002D80 */
}
a:hover {
text-decoration: underline;
}
hr {
border-top: 1px solid rgba(0, 0, 0, 0.35);
border-bottom: 0;
border-left: 0;
border-right: 0;
}
table {
text-indent: 0; margin: 0 0.5em;
}
td {
border-top: 0;
margin: 0 0.5em;
}
em {
font-style: normal;
-webkit-text-emphasis: filled dot;
}
strong {
font-family: "BIZ UDGothic", sans-serif;
font-style: normal;
font-weight: 700;
}
.warning {
padding: 3px 0;
background: black;
color: white;
font-family: 'BIZ UDGothic', sans-serif;
font-weight: 700;
}
/* ゴシック本文
body {
font-family: "BIZ UDGothic", sans-serif;
}
*/
/* 文字詰め 記入済み値は既定
p {
margin-bottom: 1em;
}
h2 {
font-size: 1.35em;
margin-top: 24px;
margin-bottom: 16px;
}
h3 {
font-size: 1.25em;
margin-top: 24px;
margin-bottom: 16px;
}
body {
line-height: 1.6;
}
*/
</style>
<!--
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_CHTML"></script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
}
});
</script>
-->
#
補足
Markdown PDF のヘッダ
Markdown PDF のヘッダについては,あまり自由度が高くない。
タイトルがファイル名になってしまうため非表示とした。設定からその都度手で打てばタイトルをヘッダに出すことはできるが,続かないと考えたのでそもそも消すことを選んだ。
日付は YYYY-MM-DD 形式で悪くないのだが,PDF が作られた日になってしまい,文書を配る日にできない。設定からその都度手で打てばタイトルをヘッダに出すことはできるが,続かないと考えたのでそもそも消すことを選んだ。
参考
Markdown PDF の導入
- https://github.com/yzane/vscode-markdown-pdf
- yzane
- Markdown PDF
- GitHub
- 参照 2025-05-06
VSCode における Markdown PDF の設定
- https://mseeeen.msen.jp/vscode-markdown-pdf-v1-header-footer-settings/
- Kenji YAMADA (kenzauros)
- VSCode markdown-pdf でヘッダーやフッターをいい感じに設定する
- MSeeeeN
- 参照 2025-05-06
- https://qiita.com/reona396/items/40b234108f7664267db8
- @reona396
- VSCodeとMarkdownで技術同人誌書いたので拡張機能とかまとめ
- Qiita
- 参照 2025-05-06
- https://codeknowledge.livedoor.blog/archives/13522085.html
- NAITO Tokihiro
- Markdown PDFのヘッダやフッタ
- Code Knowledge
- 参照 2025-05-06
VSCode における Markdown のスニペット
Markdown における PDF 上の改行
- https://blog.mmmcorp.co.jp/2018/11/16/markdown-to-pdf-document/
- 西藤翔太朗
- Markdownを印刷しやすいPDFにする時に私がしていること
- デロイト トーマツ ウェブサービス株式会社 公式ブログ
- 参照 2025-05-06
- https://qiita.com/0xmks/items/4fec4116bb42120f5180
- @0xmks
- VScodeのMarkdownからPDF変換時に改ページを挿入
- Qiita
- 参照 2025-05-06
HTML における em と strong
- https://planbworks.net/html5-em-strong.html
- すずきのりえ
- HTML5での
<em>と<strong>の違い - Plan B works
- 参照 2025-05-06
CSS の圏点
- https://developer.mozilla.org/ja/docs/Web/CSS/text-emphasis
- Mozilla
- text-emphasis
- MDN Web Docs
- 参照 2025-05-06
- https://doctor-martin.blog/2022/01/02/css-text-emphasis-vs-radial-gradient/
- 青木正幸
- CSSによる圏点について2パターンを紹介
- Dr. Martin’s Blog
- 参照 2025-05-06
等幅フォント
- https://terkel.jp/archives/2009/11/courier-courier-new-and-consolas/
- 鈴木丈
- Courier、Courier New、Consolas
- terkel.jp
- 参照 2025-05-06
- https://m.designbits.jp/13051409/
- @kasumii
- プログラミング用フォントをまとめてみました(Source Code Pro/Ricty/Consolasなどなど)
- memobits
- 参照 2025-05-06
- https://tecnogaido.one/6018/
- tecnogaido.one
- Windows標準のプログラミング用フォント5選:コードの読みやすさを高める
- tecnogaido.one
- 参照 2025-05-06
その他
- https://qiita.com/reona396/items/8ad9a4ca59f10257e073
- @reona396
- VS CodeとMarkdownで書いた技術同人誌に導入したCSS組版
- Qiita
- 参照 2025-05-06
改訂
- 改訂: 2025-11-16
- 「スタイルシート」を更新した。
- 改訂: 2025-05-20
- 「スタイルシート」を更新した。フォントサイズを調整し,MathJax を既定ではコメントアウトすることにした。