CommonMark パラグラフを理解したい

# CommonMark パラグラフを理解したい

Markdown では、ブロックやインラインの記法以外の文字はパラグラフとして解釈されるようになる。

このパラグラフについて理解したい。

## ■ Markdown におけるパラグラフ

Markdown は HTML に変換するためのサブセット的記法のため、Markdown におけるパラグラフとは `<p>` で囲われる部分を指す。

```markdown: Markdown
Here is paragraph text.
```

⇓

```html: HTML
<p>Here is paragraph text.</p>
```

パラグラフのインデントは半角スペース 3 つ分までが許容される。このインデントの半角スペースは無視される。パーサによっては半角スペース以外の Unicode 空白文字についても無視される場合がある。

このようなパラグラフを別のものとして表したい場合には、1 つ以上の空白行を挟めばよい。2 つ以上の空白行は無視される。

```markdown: Markdown
Here are

two paragraphs.
```

⇓

```html: HTML
<p>Here are</p>
<p>two paragraphs.</p>
```

## ■ パラグラフ内の半角スペース

パラグラフ内の半角スペースは保持される。

```markdown: Markdown
Here is             paragraph text.
```

⇓

```html: HTML
<p>Here is             paragraph text.</p>
```

しかし、`<p>` の影響によって 2 つ以上の半角スペースは 1 つにまとめられる。

もしも、2 つ以上の連続する半角スペースを行中に含めたい場合は、`&nbsp;` を利用すると良い。

## ■ 複数行にまたがるパラグラフソース

Markdown におけるパラグラフはソース内で複数行に渡った場合であっても、同一のパラグラフだと解釈する。

```markdown: Markdown
Here is
paragraph text.
```

⇓

```html: HTML
<p>Here is
paragraph text.</p>
```

このような結果を得る場合、`Here is` と `paragraph text` の間に半角スペースまたは強制改行 (`<br>`) が挿入される。この挿入される文字の違いは、パーサによって指定されている。このようなソース内の改行を Soft line breaks と呼ばれる。

パラグラフの 2 行目以降では、インデントをいくつでも許容する。これは、lazy 性に由来する。

```markdown: Markdown
Here is
    paragraph
          text.
```

⇓

```html: HTML
<p>Here is
paragraph
text.</p>
```

### ▽ 改行される不思議なパラグラフ

HTML ブロックの内、タイプ 7 に相当する HTML タグは、行頭であっても interrupt しない。

これを利用すると、Qiita のような Soft line breaks を改行と見なす場合、同一パラグラフであっても改行が複数回含まれる。

```markdown: Markdown
これは
<strong>
強調
</strong>
された文です。
```

⇓

```html: HTML
<p>これは<br>
<strong><br>
強調<br>
</strong><br>
された文です。</p>
```

⇓

これは
<strong>
強調
</strong>
された文です。

HTML へのパース結果を見れば明らかなように、この文章は全体が `<p>` で囲まれており、同一パラグラフ内にある。

これを悪用すれば、意味のない HTML タグを利用して奇妙なパラグラフを作成することが出来る。

```markdown: Markdown
Here is
<foo>
<foo>
<foo>
<foo>
<foo>
paragraph text.
```

⇓

Here is
<foo>
<foo>
<foo>
<foo>
<foo>
paragraph text.

## ■ 強制改行

パラグラフ内で強制的に改行したい場合、行末に半角スペースを 2 つ置くかバックスラッシュを置く。このような強制的な改行を Hard line breaks と呼ぶ。

```markdown: Markdown
<!--    ↓ ここに半角スペースを 2 つ -->
Here is
paragraph text.

Here is\
paragraph too.
```

⇓

```html: HTML
<p>Here is<br>
paragraph text.</p>
<p>Here is<br>
paragraph too.</p>
```

### ▽ HTML タグによる強制改行

強制改行を示す HTML タグ `<br>` を利用することで、どこでも改行を示すことが出来る。`<br>` であれば、1 行であることを要請するような Leaf blocks 内（ATX スタイル見出し、表など）であっても改行することが出来る。

## ■ テーマ区切り

テーマ区切り (Thematic breaks) は節内のテーマの区切りを表現する。HTML では、`<hr>` に対応している。

記法は、1 行内に 3 つ以上の `-`、`*`、`_` のいずれかのみがあれば良い。（本記事では連続する 5 つで表現する）

```markdown
-----
*****
_____
```

-----
*****
_____

`-` によるテーマ区切りには注意が必要になる。パラグラフに連続してテーマ区切りが構成される場合、Setext スタイル見出しとなる。

```markdown: Markdown
Paragraph text
-----
```

⇓

```html: HTML
<h2>Paragraph text</h2>
```

Setext スタイル見出し記法との競合を避けるために、前後に空白行を設けると良いだろう。

`*` や `_` によるテーマ区切りは Setext スタイル見出しに利用されないため、この問題を気にする必要はない。

```markdown: Markdown
Paragraph text
*****

Paragraph text
_____
```

⇓

```html: HTML
<p>Paragraph text</p>
<hr>
<p>Paragraph text</p>
<hr>
```

最後に、MDN によるテーマ区切り (`<hr>`) の説明を挙げておきたい。Markdown におけるテーマ区切りの使い方についても、以下の説明に準じると良いだろう。

> > HTML の `<hr>` 要素は、段落レベルの要素間において、テーマの意味的な区切りを表します。例えば、話の場面の切り替えや、節内での話題の転換などです。
> >
> > 以前はこれは水平の区切り線として定義されていました。現在でもブラウザーでは水平線として表示されますが、この要素は表示論的な用語ではなく意味論的な用語で定義されましたので、水平線を引きたいのであれば、適切な CSS を使用して行うようにしてください。
>
> [`<hr>`: 主題区切り (水平線) 要素 - HTML: HyperText Markup Language | MDN](https://developer.mozilla.org/ja/docs/Web/HTML/Element/hr)

# 参考

- [CommonMark spec \- 0.30](https://spec.commonmark.org/0.30)
    - [§ 4.8 Paragraphs](https://spec.commonmark.org/0.30/#paragraphs)
    - [§ 4.1 Thematic breaks](https://spec.commonmark.org/0.30/#thematic-breaks)
    - [§ 4.9 Blank lines](https://spec.commonmark.org/0.30/#blank-lines)
    - [§ 6.7 Hard line breaks](https://spec.commonmark.org/0.30/#hard-line-breaks)
    - [§ 6.8 Soft line breaks](https://spec.commonmark.org/0.30/#soft-line-breaks)
    - [§ 6.9 Textual content](https://spec.commonmark.org/0.30/#textual-content)
- [`<hr>`: 主題区切り (水平線) 要素 - HTML: HyperText Markup Language \| MDN](https://developer.mozilla.org/ja/docs/Web/HTML/Element/hr)


# 余談

Markdown でパラグラフを表現するのは最も簡単だが、意外とややこしい部分もある。

Markdown や HTML におけるパラグラフと意味的な段落とは意を異にするらしい。そのため、本記事では “段落” ではなく “パラグラフ” としている。

# 追記

2023/02/02: テーマ区切りについて追記。