25 September 2024

Python-MarkdownでMarkdownをHTMLに変換

かんたんなHTML文章を書くときに、HTMLタグを手動で記述するよりも、Markdownで書いてHTMLに変換したほうが楽ができる。

Markdownで記述することで、スタイルが一定程度統一される利点もあり、タグの閉じ忘れなどの細かいエラーが起こる心配もない。

オフィシャルWebサイト

Python-Markdown
Extensions(拡張機能)
Sitemap(もくじ)

最初の第一歩。最も単純な変換スクリプト

Python-Markdown のPythonコード スケルトンは次のようなものである

md2html.py
import markdown

inputFilename = "input.md"
outputFilename = "output.html"
txtMarkdown = ""

# ファイル(Markdownファイル)から入力
with open(inputFilename) as f:
    txtMarkdown = f.read()

# Markdown を HTML に変換
txtHtml = markdown.markdown(txtMarkdown)

# ファイル(HTMLファイル)に出力
with open(outputFilename, "w") as f:
    f.write(txtHtml)

拡張機能

たとえば、次のようなMarkdown記述をHTML変換するには、拡張機能を使う必要がある。

  • 表(table)の変換
  • ``` で囲った文字列を pre に変換
  • セクションを目次に変換
  • 脚注

拡張機能の一覧は次のようなもので、

20240925-extention-list.jpg

これらを使うときの記述方法の例を示す。

md2html.py の 変換部分の抜粋
設定パラメータを拡張機能のクラス初期化時の引数で扱う場合
import markdown

from markdown.extensions.toc import TocExtension
from markdown.extensions.footnotes import FootnoteExtension

listExtensions = [
    'tables',
    'nl2br',
    'fenced_code',
    FootnoteExtension(PLACE_MARKER='///脚注///'),
    TocExtension(baselevel=3)]

txtHtml = markdown.markdown(txtMarkdown, extensions=listExtensions)
md2html.py の 変換部分の抜粋
設定パラメータを辞書で渡す場合
import markdown

listExtensions = [
    'tables',
    'nl2br',
    'fenced_code',
    'footnotes',
    'toc']

dictConfigs = {'footnotes': {'PLACE_MARKER': '///脚注///'},
    'toc': {'baselevel': 3}}

txtHtml = markdown.markdown(txtMarkdown, extensions=listExtensions, extension_configs=dictConfigs)

変換例

太字、斜体、取り消し線

取り消し線は変換できなかった。

Markdown
斜体 : 故人 *西のかた黄鶴楼を辞し* 煙花三月 揚州に下る

太字 : 故人 **西のかた黄鶴楼を辞し** 煙花三月 揚州に下る

太字&斜体 : 故人 ***西のかた黄鶴楼を辞し*** 煙花三月 揚州に下る

取消 : 故人 ~~西のかた黄鶴楼を辞し~~ 煙花三月 揚州に下る

変換の結果は

HTML
<p>斜体 : 故人 <em>西のかた黄鶴楼を辞し</em> 煙花三月 揚州に下る</p>
<p>太字 : 故人 <strong>西のかた黄鶴楼を辞し</strong> 煙花三月 揚州に下る</p>
<p>太字&斜体 : 故人 <strong><em>西のかた黄鶴楼を辞し</em></strong> 煙花三月 揚州に下る</p>
<p>取消 : 故人 ~~西のかた黄鶴楼を辞し~~ 煙花三月 揚州に下る</p>

見出し H1, H2, ... と、目次(TOC)

Markdownファイルに [TOC] と書かれた場所に、HTMLでは「もくじ」が作成される。下の変換例では 'toc': {'baselevel': 3}} の設定で変換したため、Markdownの見出しレベル1以下が、HTMLではレベル3以下に変換されている。

Markdown
# Markdownのサンプル
[TOC]
## 太字、斜体、取り消し線
## 水平線
## リンク

変換の結果は

HTML
<h3 id="markdown">Markdownファイルのサンプル</h3>

<div class="toc">
<ul>
<li><a href="#markdown">Markdownファイルのサンプル</a><ul>
<li><a href="#_1">太字、斜体、取り消し線</a></li>
<li><a href="#_2">水平線</a></li>
<li><a href="#_3">リンク</a></li>
</ul>
</li>
</ul>
</div>

<h4 id="_1">太字、斜体、取り消し線</h4>
<h4 id="_2">水平線</h4>
<h4 id="_3">リンク</h4>

表 table

Markdown
| 通貨コード | 国             | 円換算  |
| ---------- | -------------- | ------- |
| USD        | アメリカ       | 145.8円 |
| AUD        | オーストラリア | 98.3円  |
| GBP        | イギリス       | 191.3円 |
| EUR        | 欧州統一通貨   | 161.1円 |

変換結果は次の通り

HTML

<table>
<thead>
<tr>
<th>通貨コード</th>
<th>国</th>
<th>円換算</th>
</tr>
</thead>
<tbody>
<tr>
<td>USD</td>
<td>アメリカ</td>
<td>145.8円</td>
</tr>
<tr>
<td>AUD</td>
<td>オーストラリア</td>
<td>98.3円</td>
</tr>
<tr>
<td>GBP</td>
<td>イギリス</td>
<td>191.3円</td>
</tr>
<tr>
<td>EUR</td>
<td>欧州統一通貨</td>
<td>161.1円</td>
</tr>
</tbody>
</table>

リスト(箇条書き)

Markdown
順序なしリスト

- 項目1
- 項目2
  - 項目2-1
  - 項目2-2
- 項目3

順序付きリスト

1. 項目1
2. 項目2
   1. 項目2-1
   2. 項目2-2
1. 項目3

変換結果は次の通り。階層(入れ子)リストは変換できていない。

HTML
<p>順序なしリスト</p>
<ul>
<li>項目1</li>
<li>項目2</li>
<li>項目2-1</li>
<li>項目2-2</li>
<li>項目3</li>
</ul>
<p>順序付きリスト</p>
<ol>
<li>項目1</li>
<li>項目2</li>
<li>項目2-1</li>
<li>項目2-2</li>
<li>項目3</li>
</ol>

タスクリスト(チェックリスト)

Markdown
タスクリスト

- [ ] タスク1
- [x] タスク2
- [ ] タスク3

次のように変換される

HTML
<p>タスクリスト</p>
<ul>
<li>[ ] タスク1</li>
<li>[x] タスク2</li>
<li>[ ] タスク3</li>
</ul>

URLリンク

Markdown
文章中にリンク(例:[Google検索](https://www.google.com))を記述できます

次のように変換される

HTML
<p>文章中にリンク(例:<a href="https://www.google.com">Google検索</a>)を記述できます</p>

画像

Markdown
![Apache Server Logo](https://upload.wikimedia.org/wikipedia/commons/4/45/Apache_HTTP_server_logo_%282016%29.png)

Apache Server Logo

次のように変換される

HTML
<p><img alt="Apache Server Logo" src="https://upload.wikimedia.org/wikipedia/commons/4/45/Apache_HTTP_server_logo_%282016%29.png" /></p>
<p>Apache Server Logo</p>

プログラムのコード

ソースコード
通常文の中(バッククオート1個で囲む  \` ...... \` )

`printf` 関数は、一連の文字や値の書式を指定し、標準出力ストリーム `stdout` に出力します。

コードブロック(バッククオート3個で囲む  \`\`\` ...... \`\`\` ) : python-markdown の fenced_code 拡張機能で変換可能

```
#include<stdio.h>

void main(void) {
    printf("Hello World\n");
}
```

あるいは、行頭を空白(スペース×4)インデントとする

    #include<stdio.h>

    void main(void) {
        printf("Hello World\n");
    }

次のように変換される

HTML
<p>通常文の中(バッククオート1個で囲む  ` ...... ` )</p>
<p><code>printf</code> 関数は、一連の文字や値の書式を指定し、標準出力ストリーム <code>stdout</code> に出力します。</p>
<p>コードブロック(バッククオート3個で囲む  ``` ...... ``` ) : python-markdown の fenced_code 拡張機能で変換可能</p>
<pre><code>#include&lt;stdio.h&gt;

void main(void) {
    printf(&quot;Hello World\n&quot;);
}
</code></pre>
<p>あるいは、行頭を空白(スペース×4)インデントとする</p>
<pre><code>#include&lt;stdio.h&gt;

void main(void) {
    printf("Hello World\n");
}
</code></pre>