Markdown の強制改行がややこしい

<!-- # Markdown の強制改行がややこしい -->

Markdown では、文章中で改行しても改行されずに半角スペースになる場合があります。

これを強制的に改行する方法を紹介します。

:::note info
本記事では、ソース内文章中の 1 つ改行を Soft line break、明示的な改行を Hard line break と呼称します。（CommonMark と同じ）

また、半角スペースを `␣`、改行を `↵` として明示的に表現しています。
:::

## 明示的に改行する

Markdown ソース内で明示的に改行する場合、以下の 2 通りが主流です。この明示的な改行を Hard line break と呼びます。

- 連続した 2 つの半角スペース＋改行：`␣␣↵`
- バックスラッシュ＋改行：`\↵`

```markdown: 明示的な改行の例
ここで␣␣↵
改行します。

ここでも\↵
改行します。
```

これらの明示的な改行は `<br>` として解釈されます。

しかし、このような明示的な改行が任意の Markdown 仕様に含まれているわけではありません。

### 仕様と Hard line break

Markdown は John Gruber によるオリジナル Markdown から派生して多くの仕様が存在します。

これらの仕様それぞれによって、Hard line break をどのように表現するか異なります。

そこで、主要な Markdown 仕様の Hard line break がどのように表現できるか表にしました。

| 仕様                         | `␣␣↵` |   `\↵`   | その他 |
| ---------------------------- | :---: | :------: | :----: |
| (Original) [Markdown][]      |  ✓   |          |        |
| [CommonMark][]               |  ✓   |    ✓    |        |
| [Djot][]                     |       |    ✓    |        |
| [kramdown][]                 |  ✓   |          | `\\↵`  |
| [MultiMarkdown][]            |  ✓   |    ✓    |        |
| [Pandoc’s Markdown][pd-m]    |  ✓   | ✓[^elb] |        |
| [PHP Markdown Extra][php-me] |  ✓   |          |        |
| [Python-Markdown][]          |  ✓   |          |        |

[markdown]: https://daringfireball.net/projects/markdown/syntax#p "Daring Fireball: Markdown Syntax Documentation"
[commonmark]: https://spec.commonmark.org/current/#hard-line-breaks "CommonMark Spec"
[djot]: https://htmlpreview.github.io/?https://github.com/jgm/djot/blob/master/doc/syntax.html#line-break "Djot syntax reference"
[kramdown]: https://kramdown.gettalong.org/syntax.html#paragraphs "Syntax | kramdown"
[multimarkdown]: https://rawgit.com/fletcher/MultiMarkdown-6-Syntax-Guide/master/index.html "MultiMarkdown v6 Syntax Guide"
[pd-m]: https://pandoc.org/MANUAL.html#paragraphs "Pandoc - Pandoc User’s Guide"
[php-me]: https://michelf.ca/projects/php-markdown/extra/ "PHP Markdown Extra"
[python-markdown]: https://python-markdown.github.io/ "Python-Markdown — Python-Markdown 3.6 documentation"

[^elb]: デフォルトでは使えず、`escaped_line_breaks` を有効にする必要があります。

HTML が利用可能なのであれば、`<br>` でも強制改行できます。

## Soft line break が強制改行に解釈される場合

Qiita のように Soft line break（ソース内の文書改行）が強制改行に解釈される場合、通常の改行だけでも改行されます。[^slb2br]

[^slb2br]: Soft line break が強制改行にも解釈される仕様の幅は CommonMark しか明記されていません。（Qiita の Markdown は CommonMark を拡張しています）

<table><tbody>
<thead>
  <tr> <th>Markdown</th>
  <th> ⇒ </th>
  <th>HTML</th> </tr>
</thead>
<tr> <td>

```markdown
Hard
line break
```

</td> <td> ⇒ </td> <td>

```html
Hard<br>
line break
```

</td> </tr>
</tbody> </table>

ここに Hard line break による強制改行を行っても、2 重の強制改行にはなりません。（`<br>` が連続しない）

<table><tbody>
<thead>
  <tr> <th>Markdown</th>
  <th> ⇒ </th>
  <th>HTML</th> </tr>
</thead>
<tr> <td>

```markdown
Hard\
line break
```

</td> <td> ⇒ </td> <td>

```html
Hard<br>
line break
```

</td> </tr>
</tbody> </table>

ただし、`<br>` を明示的に利用する場合、2 重の強制改行になってしまいます。

<table><tbody>
<thead>
  <tr> <th>Markdown</th>
  <th> ⇒ </th>
  <th>HTML</th> </tr>
</thead>
<tr> <td>

```markdown
Hard<br>
line break
```

</td> <td> ⇒ </td> <td>

```html
Hard<br><br>
line break
```

</td> </tr>
</tbody> </table>

----------

CommonMark を拡張した [GFM][] が使われている GitHub\.com では、改行が強制改行に解釈される領域（Issues や PRs、そのコメント等）と改行が無視され半角スペースになる領域（リポジトリのファイルや Gist 等）があります。

[gfm]: https://github.github.com/gfm/#hard-line-breaks "GitHub Flavored Markdown Spec"

文章の途中で改行したいと強く願うならば、`<br>` で強制改行するよりも `\↵` を利用した方が良いでしょう。

## 余談

「Markdown では `␣␣↵` で強制改行しなくてはならないのは不便だ」と言う主張もありますが、多くの場合で `\↵` でも改行できます。
`\↵` を使いましょう。