Markdownの改行が反映されない理由と、日本語で書くときの対処法

仕事柄や自分用メモでMarkdown記法に触れることが多々ある。このサイトの文章も基本的にはMarkdown記法である。

VSCode(Visual Studio Code)で書いているが、他のMarkdownツールと比べると不便な部分もある。とくに引っかかるのが改行だ。エディタ上では改行したはずなのに、公開したページでは前の行とつながってしまう。

本記事ではその理由と、改行のやり方の使い分けを整理する。

なぜ改行が反映されないのか

Markdownでは、ソース上の1回の改行は「ソフトブレイク」として扱われる。これはHTMLに変換される際に空白1つと同じ扱いになり、<br>にはならない。

一行目
二行目

これは次のように変換される。

<p>一行目
二行目</p>

HTMLは連続する空白や改行を1つの空白にまとめて表示するため、ブラウザ上では「一行目 二行目」と横に並ぶ。エディタのソースだけ見ていると改行できている気になるが、出力は別物というわけだ。

一方、空行を1つ入れると段落が変わる。こちらは<p>タグそのものが分かれるので、確実に行が分かれる。つまり「段落を分けたい」のであれば空行で足りる。問題になるのは、段落の中で行だけを変えたいときである。

段落の中で改行する3つの方法

方法書き方ソース上で見えるか
半角スペース2つ行末に半角スペースを2つ置く見えない
バックスラッシュ行末に\を置く見える
brタグ行末に<br>を直接書く見える

3つとも出力は同じ<br>になる。違いはソース上で見えるかどうかだ。

正式なMarkdown記法(CommonMark)で規定されているのは、行末の半角スペース2つである。プレビューを出していれば気づけるが、プレビュー無しで編集しているとなかなか気付けない。

バックスラッシュも同じくCommonMarkで定義された書き方で、出力は変わらない。スペースと違って文字として見えるのが利点だ。

<br>を直接書く方法も動く。Markdownはインラインの生HTMLをそのまま通すためである。ただしMarkdownの中にHTMLが混ざるので、他ツールへ移すときに扱いが変わることがある。

日本語で書くと何が起きるか

日本語入力中は全角モードになっているため、行末で半角スペースを2つ入れるのが単純に手間になる。IMEをオフにして2回叩いて、また戻す。1回なら大した操作ではないが、記事1本ぶん繰り返すと地味に効いてくる。

さらに厄介なのが、末尾の半角スペースは見えないという点だ。見えないので、次の2つが起きやすい。

  • エディタやフォーマッタの「行末スペースを削除」設定に、書いたそばから消される
  • Gitの差分では意味のある変更なのに、目視ではどこが変わったのか分からない

バックスラッシュを選ぶ理由はここにある。文字として残るので、消される事故も差分の読みにくさも避けられる。

もう1つ、日本語特有の落とし穴として、ソフトブレイクが空白に変換される件がある。英語なら単語の区切りに空白が入るだけで自然だが、日本語は単語を空白で区切らないため、文の途中に不自然な空白が入って見えることがある。段落の途中で気軽に改行を入れる書き方は、日本語だと裏目に出やすい。

なお、ツールによってはこの挙動自体が違う。使ったことのある以下のMarkdownツールでは、Enter1つでの改行に対応する仕組みがある。

  • Inkdrop — 公式プラグインにてEnter1つでの改行に対応
  • Obsidian — 厳密な改行設定によってEnter1つでの改行に対応
  • Qiita — デフォルトでEnter1つでの改行に対応

書き味は圧倒的に楽だが、同じ.mdファイルを別のツールに持っていくと出力が変わる。ツールに最適化した書き方は、そのツールから出た瞬間に崩れると考えたほうがいい。

静的サイトジェネレータ側で挙動を変えることもできる。当サイトはAstroで動いているが(Astroでのサイト構築についてはこちら)、Astroが内部で使うremarkにはremark-breaksというプラグインがあり、これを入れるとソフトブレイクが<br>になる。ただし全記事の出力が一斉に変わるので、既存記事の見た目を確認せずに入れるものではない。

VSCodeでの対処

VSCodeでMarkdown記法を書き、GitHubにPush、Netlifyで公開という流れだと、正式なマークダウンの形式に従うのが結局は無難である。その上で、ミスに気づける状態を作っておく。

Ctrl + Shift + V でプレビュー

VSCode標準機能としてMarkdownのプレビューが存在する。見出し、箇条書き、改行が正しいかすぐチェックできるので、改行し忘れのミスはまず起こらない。右上にサイドバイサイドで表示するアイコンもあるため、場所がわからないということはないと思う。

スペースを視覚的に表示する

見えないものは見えるようにする。VSCodeではスペースを表示できる。

ファイル→ユーザー設定→設定→Editor: Render Whitespace

  • none 表示しない
  • boundary 単語間の単一スペース以外
  • selection 選択したテキストのみ表示
  • trailing 末尾の空白のみ表示
  • all 全部表示

行末スペースだけ見えれば用は足りるので、trailingが扱いやすい。

行末スペースを消させない

「行末の空白を削除」する設定が有効だと、せっかく入れた半角スペース2つが保存時に消える。Markdownだけ除外するなら、settings.jsonに次のように書く。

{
  "files.trimTrailingWhitespace": true,
  "[markdown]": {
    "files.trimTrailingWhitespace": false
  }
}

記法は正しいのに反映されないという場合、原因がエディタ側にあることは珍しくない。

おわりに

整理すると、使い分けはこうなる。

  • 段落を分けたいときは空行。これが基本で、ツールを移っても崩れない
  • 段落の中で改行したいときは半角スペース2つが正式。ただし見えないぶん事故りやすいので、バックスラッシュでも構わない

せっかくだからちゃんとしたMarkdown記法を操れるように、末尾の半角スペース2つには慣れておくことにする。とはいえ、消えて困った経験が続くようならバックスラッシュに寄せればいい。どちらも正式な記法である、というのが今回いちばんの収穫だった。