ミケガモのブログ

AtomのMarkdownシンタックスハイライトが日本語文に適用されない問題

※ 2021/8/5 自分の環境を変えたので追記。

はじめに

Atomエディタのlanguage-gfm, および language-markdownパッケージは、 日本語の全角記号の前後でMarkdownの斜体・太字記法を使った場合、 シンタックスハイライトが適用されない(下図)。

f:id:mikegamo:20210630165008j:plain

今回は、language-gfm-enhanced, もしくは language-markdownの設定ファイルを書き換えることで、これを解決した。

language-markdownのほうのファイルはGithubにアップロードしたので、 必要な方はダウンロードして使ってほしい。 ただし、ご利用は自己責任で。

注記しておくと、language-gfmとlanguage-markdownMarkdownシンタックス用パッケージ。 language-gfmはコアパッケージ(デフォルトでインストールされている)で、 language-markdownはコミュニティパッケージ(自分でインストールする)である。 使用時はいずれか1つだけを適用することになるため、併用はできない。 この記事の説明は、自分が使いたいパッケージの方だけを読めば十分。

方法

language-gfmを使う場合

1. language-gfm-enhancedパッケージをインストールする。

language-gfmはコアパッケージなので、設定ファイルをいじるのが困難。 そこで、この機能を拡張したコミュニティパッケージ、 「language-gfm-enhanced」パッケージをインストールして、 その設定ファイルを編集することにする。

2. 以下のファイルを開く。

C:\Users\(ユーザー名)\.atom\packages\language-gfm-enhanced\grammars\gfm.cson

3. gfm.csonの中身を書き換える。

書き換えるのは以下の部分。 「markup.bold.gfm」で検索し、1つ目のセクションのbeginendの計2行を変更する。

{
  'begin': '(?<=^|[^\\*])\\*\\*(?!$|\\*|\\s)'
  'end': '(?<!^|\\s)\\*\\**\\*'

  ### '(?<=^|[^\\w\\d\\*])\\*\\*(?!$|\\*|\\s)' 変更前
  ### 'end': '(?<!^|\\s)\\*\\**\\*(?=$|[^\\w|\\d])' 変更前

  'name': 'markup.bold.gfm'
  'patterns': [
    {
      'match': '(&)([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;)'
      'name': 'constant.character.entity.gfm'
      'captures':
        '1':
          'name': 'punctuation.definition.entity.gfm'
        '3':
          'name': 'punctuation.definition.entity.gfm'
    }
  ]
}

language-markdownを使う場合

0. 前提

Atomのlanguage-markdownパッケージがインストールされている。

1. 以下のページから、language-markdown.json をダウンロードする。

github.com

2. 以下にあるファイルを、ダウンロードしてきたものに置き換える。

C:\Users\(ユーザー名)\.atom\packages\language-markdown\grammars\language-markdown.json

language-markdownパッケージをアップデートもしくは再インストールすると、 元の設定に戻る。

結果

解決した。

f:id:mikegamo:20210630165018j:plain

調べたこと・やったこと

問題解決のために色々調べていたところ、 Markdownシンタックスハイライトを日本語に対応させるパッケージ「language-mdbp」を発見した。

しかし、このパッケージをそのままインストールしても、ハイライトは上手く機能しなかった。 そこで、このパッケージのハイライト条件文を、 language-gfm-enhancedおよびlanguage-markdownの設定ファイルに移植することにした。

なお、language-mdbpの最新版ver1.80は、製作者様が日本語強調表示を廃止している。 そのため、強調表示が有効なver1.7.1のスクリプトを参照した。

atom.io

スクリプトの中から、 language-mdbp > grammars > mdbp.cson 内の「bold」を含むブロックを探し、

  • gfm.csonの該当ブロックと異なる部分をgfm.csonへ移植した。
  • ブロック計4つを、language-markdown.jsonemphasis ブロックの中にコピーした。
    • nameの値はコピー先の設定に合わせた。
    • .cson.jsonは少し記法が違うので、適宜修正した。

ちなみに、ハイライトを適用するための文字列検索は、 正規表現の機能をさらに強化したパッケージ「鬼車」の記法に則っている。 これを理解してコーディングする方法もあったが、難しそうだったのでやめた。

flight-manual.atom.io

github.com

どうしてこんなことに?

Markdownはもともと、英語のように単語間にスペースがある言語で使われることを想定している。 日本語での挙動がおかしくなるのは仕方ない。

単語の前後に半角スペースを入れればその場しのぎにはなるが、 普通に面倒くさいし、 書き上がったものにも微妙にスペースが入ってしまうのがイヤだ。

他のエディタ

Atomがダメなら他のエディタに移行しようか……と思ったが結局断念した。

Typora

割と良さそうではあった。

Markdownエディタとしての機能はすごい。 エディタで編集している部分が、そのままMarkdownプレビューになる。 カーソルを乗せた時だけ構文用の文字が表示されるのは天才だと思った。

しかし、自分は既にAtom本体のショートカットキーに慣れてしまった。 Ctrl + dの複数単語選択や、Ctrl + ↑↓の行入れ替えが無いと落ち着かない。 シンタックスキーバインドの拡張性も、Atomの方が高い。

Typora側のデメリットとしては、表示フォントを気軽に変えられないところが挙げられる。 .cssを編集すれば対応は可能。

VS code

Alt + ↑↓で行入れ替えが出来るのを知っていたので試してみたが、 こちらもやはりハイライトが不完全だった。

おまけ:language-markdownシンタックステーマ

language-markdownパッケージは、シンタックスハイライトに独自の構文を使用している。 そのため、ハイライトを使えるシンタックステーマが、 配布ページに明記されているものと、有志によるいくつかの専用パッケージしかない。

はじめはlanguage-markdownの機能に期待してこちらを使っていたのだが、

  • 機能はmarkdown-writerパッケージで十分
  • シンタックステーマはメジャーなものを使っておいたほうが良さそう

という理由で、language-gfmに戻すことにした。

自分がlanguage-markdownを導入した当初は、gl-md-syntaxテーマが気に入ってしばらく使っていた。 ただし、このテーマで気になったのが、

  • 太字にした部分が斜体で表示されてしまう
  • バックスラッシュとその次の1文字に色がついてしまう

ことの2点。

これは、gl-md-syntax > styles 内のファイルを編集することで解決できた。 編集内容は以下の2個。

  • markup-and-down.less
 &.emphasis {
  &:not(.strong) {}

  &:not(.strong){
    // font-style: italic; ←コメントアウトした
  }
  • base.less
.syntax--constant {
  // color: @dark-blue;
    color: @syntax-text-color;

  &.syntax--character.syntax--escape {
    color: @light-blue;
  }

おわりに

AtomMarkdown用のエディタにする、という記事は数多く出ているのだが、 今回の問題について言及したページは「language-mbdp」の製作者様の1件しか見当たらなかった。

みんな困ってないのかな。