MarkdownをPDFに!Pythonのパワーで実現する変換テクニック

私はほぼMarkdownファイルでメモを取っています。

ja.wikipedia.org

Markdownファイルは記述はとても簡単でWordなどとは異なりレイアウトは最低限度という感じではありますが、対応したViewerでレンダリングを行うことで割と見栄えが良くなる点で非常に重宝しています。それをかなりカバーしてくれているのはHackMDというサービスでMarkdownファイルをレンダリングしながら編集ができ、作成したファイルはHTMLなどで共有ができるので大変助かっていました。

hackmd.io

そんな状況だったのですが、会社でHackMDのサイトアクセスが制限されてしまいました。とても悲しい😭

うちの会社はエディタのインストールが使用できないため、Visual Studio Codeが使用できません。そのため、vscode.dev(オンライン版のVisual Studio Code)でを使用してメモを取ることにしました。起動に時間はちょっとかかりますが、WPAとして起動はできるのでそこまでつらくはないです。編集こそ楽なのですが、情報の共有というところではレンダラーが相手にないこともあり、今一有効につかえてないなと思っています。

vscode.dev

そこで、作成したMarkdownをPDFファイルに変換するものがあると助かるかなと思ってPythonで作成してみました。

調べてみると、ファイルを直接変換を行うことができないので、一度HTMLファイルに変換してから、PDFファイルへ変換する作業を行います。HTMLまでの処理で止めることも可能です。HTMLにするのも便利ですね。

使用環境

今回使用した環境はUbuntu23.04、python3(Ver3.11.4 デフォルトでインストール)の環境となります。 pipコマンドはデフォルトではインストールされていないので、別途aptコマンドでインストールを行ってください。

$ sudo apt update
$ sudo apt install python3-pip

使用するライブラリ

使用するライブラリはmarkdownweasyprintを使用します。

ライブラリのインストール

$ pip install markdown weasyprint

markdownライブラリ

pypi.org


weasyprintライブラリ

pypi.org


markdownMarkdownファイルをHTML化するライブラリで、weasyprintはHTMLをPDF化する機能を持つライブラリです。

コード例

インストールしたライブラリを使用して以下のようにコードを組むことでMarkdownファイルをHTMLファイルに変換し、その後PDFファイルに変換しています。 スクリプトと同じパスにあるsample.mdを使用して、sample.htmlsample.pdfの2つのファイルを作成しています。

from markdown import markdown
from weasyprint import HTML
import os

with open('sample.md', 'r') as f:
    markdown_text = f.read()
    html_text = markdown(markdown_text)
    with open('sample.html', 'w') as f:
        f.write(html_text)
    HTML('sample.html').write_pdf('sample.pdf')

以下のようなsample.mdファイルを準備して、実行を行うと

# 条件を分岐させるためのIF文の使い方とは?
## 条件分岐って何?
条件分岐とは、指定した条件で処理を分ける方法

***
- 請求書の締め月が上期だった場合は、〇〇を使って計算する
- 部署コードがA0001の場合は開発部、B0001の場合はWEBマーケティング部
- 処理月が2014年4未満だった場合は消費税5%、それ以外は8%で計算
***
## IF文の基礎的な使い方
### 条件が1つのみ

実行後は次の様なPDFファイルが生成されます。

これでMarkdownファイルをPDFファイルのViewerで表示することができるようになりました。複雑な例はあまり試してはいませんので、そんなに期待できないかもしれません。そうなった場合にはHTMLファイルも作成されているので、そちらを使ってもいいかなと思います。

コード例2

先ほどはプログラムにファイル名を埋め込んでいましたが、続いては引数としてファイル名を入れたものになります。

markdown_to_pdf.py

import argparse
from markdown import markdown
from weasyprint import HTML
import os

def markdown_to_pdf(markdown_file_path, pdf_file_path):
    # Read the Markdown file
    with open(markdown_file_path, 'r') as f:
        markdown_text = f.read()

    # Generate the HTML file path based on the Markdown file path
    html_file_path = os.path.splitext(markdown_file_path)[0] + '.html'

    # Convert Markdown to HTML
    html_text = markdown(markdown_text)
    
    # Save the HTML content to a file
    with open(html_file_path, 'w') as f:
        f.write(html_text)

    # Convert HTML to PDF
    HTML(html_file_path).write_pdf(pdf_file_path)
    
    print(f'{pdf_file_path} has been generated.')

if __name__ == "__main__":
    # Initialize argparse
    parser = argparse.ArgumentParser(description="Convert a Markdown file to PDF.")
    
    parser.add_argument("markdown_file", help="Path to the input Markdown file.")
    parser.add_argument("pdf_file", help="Path to the output PDF file.")
    
    args = parser.parse_args()
    
    # Convert the Markdown file to PDF
    markdown_to_pdf(args.markdown_file, args.pdf_file)

使い方は以下のようになります。引数上に現れていませんが、markdownファイル(拡張子.md)の拡張子をhtmlにしたHTMLファイルを同じ場所に作成するので、ご注意ください。

実行方法は以下のような形となります。

$ python3 markdown_to_pdf.py sample.md sample.pdf

おわりに

markdownファイルからHTMLファイルを経由してPDFファイルにする方法をPythonで記述してみました。これも、実は没ネタなのですが、以前から自分が困っていたことだったので結果オーライって感じです💪

/* -----codeの行番号----- */