フロントエンド技術がなんもわからんプログラマがPythonでMarkdownをHTMLにレンダリングしてCSSを適用してみた

## 概要

### やること

- MarkdownファイルをHTMLファイルに変換して、HTMLタグへの理解を深める
- CSSの基本的な扱いに慣れる

### 想定読者

- Pythonはなんとなくわかる
- Markdownは普通にわかる
- HTML, CSSはよくわからない

### 背景

- 筆者は普段Pythonでデータ加工処理やRPAを作っている。Webアプリ開発も手を出し始めた。
- ブラウザを自動操作をするにせよ、Webアプリを作るにせよ、フロントエンドがわからないとつらい。
- Markdownには慣れている。そういえば、MarkdownってHTMLを読み書きしやすくするというコンセプトで作られたものでは...?
- MarkdownからHTMLを生成するツールを使えば、自分が書いたMarkdownとの対応がよくわかるのでは！！？

## 詳細

### ツール候補

なんやかんやでPythonを選びました。  

#### Visual Studio Code 拡張機能 Markdown All In One

なんかムチャクチャファイル内の文字が多くなった。  
スタイル関係とからしい。便利だが、読める代物ではないので今回は使わない。

#### pandoc  

簡単、シンプルで悪くないが、細かい設定がしづらい。

#### Python

Markdownライブラリ及びその拡張で変換できる。  
beautifulsoup4を使えばパースも簡単。  
文字列加工機能でスタイルシート読み込み部分を後付けすることも可能。

### マークダウンファイルの中身

以下の書式を試してみた。

- 見出し
- テキスト
- 箇条書き
- 番号付きリスト
- チェックボックス
- テーブル
- 強調
- 画像の挿入
- コードブロック

``````markdown
# largest HEADER

## second largest HEADER

texttexttexttexttexttexttexttext  

texttexttexttexttexttexttexttext

### third largest HEADER

texttexttexttexttexttexttexttext

### table

|col 1|col 2|col 3|
|---|---|---|
|xxx|111|aaa|
|yyy|222|bbb|
|zzz|333|ccc|

### list

- list
- list
- list

### list with number

1. list with number
2. list with number
3. list with number


### check list

- [x] check list
- [ ] check list
- [ ] check list

### strong text

texttext __text__ text

### code block

```python
print("hello")
```
``````

### 準備


まずはMarkdownを扱うライブラリをインストール
```bash
pip install markdown
```

チェックリスト用の拡張もインストール
```bash
pip install markdown-checklist
```
結果、なんか警告がでた...とりあえず使うことはできた。
```bash
Collecting markdown-checklist

~~~~中略~~~~

  DEPRECATION: markdown-checklist is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproject.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement is to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559
  Running setup.py install for markdown-checklist ... done
Successfully installed markdown-checklist-0.4.4
```

Beautifulsoupもインストール  
```bash
pip install beautifulsoup4
```

### Pythonスクリプト

```python
import markdown
from bs4 import BeautifulSoup

with open("./sample.md", mode="r", encoding="utf-8") as f:
    markdown_text = f.read()
    HTML = markdown.markdown(
        markdown_text, extensions=["extra", "markdown_checklist.extension"]
    )# MarkdownからHTMLへ変換

font_link = '''<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@600&family=Literata:opsz@7..72&display=swap" rel="stylesheet">\n'''
style_file_link = '<link href="style.css" rel="stylesheet">\n'
html = font_link + style_file_link + html
soup = BeautifulSoup(HTML, 'HTML.parser') # initialize BeautifulSoup
HTML = soup.prettify()# パースして読みやすく

with open("./sample.HTML", mode="w", encoding="utf-8") as f:
    f.write(HTML)
```

### スタイル(CSS)

ムチャクチャダサくなるが、こういう時は大げさにするのが大事。

```CSS
h1 {
    color: red;
    font-family: 'Crimson Pro', serif;
}

h2 {
    color: blue;
}

h3 {
    color: green;
    font-family: 'Literata', serif;
}

p {
    font-family: sans-serif;
}
table{
    border-collapse: collapse;
    border: 2px solid rgb(200,200,200);
    letter-spacing: 1px;
    font-size: 0.8rem;
}
tr, th, td{
    border: 1px solid rgb(190,190,190);
    padding: 10px ;
}
ul{
    color: red;
}
ol{
    color: blue;
}

strong {
    color: green;
}

code{
    background-color: black;
    color: white;
}
```


## 結果

### HTML

なんかものすごい改行されているが一応読める

```HTML
<link href="style.css" rel="stylesheet"/>
<h1>
 largest HEADER
</h1>
<h2>
 second largest HEADER
</h2>
<p>
 texttexttexttexttexttexttexttext
</p>
<p>
 texttexttexttexttexttexttexttext
</p>
<h3>
 third largest HEADER
</h3>
<p>
 texttexttexttexttexttexttexttext
</p>
<h3>
 table
</h3>
<table>
 <thead>
  <tr>
   <th>
    col 1
   </th>
   <th>
    col 2
   </th>
   <th>
    col 3
   </th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>
    xxx
   </td>
   <td>
    111
   </td>
   <td>
    aaa
   </td>
  </tr>
  <tr>
   <td>
    yyy
   </td>
   <td>
    222
   </td>
   <td>
    bbb
   </td>
  </tr>
  <tr>
   <td>
    zzz
   </td>
   <td>
    333
   </td>
   <td>
    ccc
   </td>
  </tr>
 </tbody>
</table>
<h3>
 list
</h3>
<ul>
 <li>
  list
 </li>
 <li>
  list
 </li>
 <li>
  list
 </li>
</ul>
<h3>
 list with number
</h3>
<ol>
 <li>
  list with number
 </li>
 <li>
  list with number
 </li>
 <li>
  list with number
 </li>
</ol>
<h3>
 check list
</h3>
<ul class="checklist">
 <li>
  <input checked="" disabled="" type="checkbox"/>
  check list
 </li>
 <li>
  <input disabled="" type="checkbox"/>
  check list
 </li>
 <li>
  <input disabled="" type="checkbox"/>
  check list
 </li>
</ul>
<h3>
 strong text
</h3>
<p>
 texttext
 <strong>
  text
 </strong>
 text
</p>
<h3>
 code block
</h3>
<pre><code class="language-python">print("hello")
</code></pre>
```

### ブラウザ画面(Chrome)

すごくダサいけど、スタイルが適用されているのがわかってよい。

![2023-02-14 232950.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2913763/7d975369-5d5c-23c7-7fbe-57fc74a2c77b.png)


## 感想

- HTMLはよくわからなかったが、Markdownと関連付けることで整理できた気がする。
- HTML,CSSがわかるとMarkdownで資料を作る場合でもとても便利。特にMarpでのスライド作りとか。
- これを活かしてDjangoでMarkdownをレンダリングできるブログを作ってみたい。目下試行錯誤中。


## 参考サイト

[ウェブ開発を学ぶ | MDN](https://developer.mozilla.org/ja/docs/Learn)