読者です 読者をやめる 読者になる 読者になる

一人GitHub会議・お気に入りのX言語のシンタックスハイライトがおかしかったらどうすればいいのか?

6/1開催のGitHub会議( http://githubkaigi.org/ )合わせのネタです。

お気に入りのX言語のシンタックスハイライトがおかしかったらどうすればいいのか?

たとえばAwkスクリプト(例: https://gist.github.com/metanest/8747791 )のシンタックスハイライトを見ると、今日現在で、

  • elseがキーワードとして認識されないため強調されない
  • intという識別子の"in"の部分だけがin演算子扱いされて強調されている

といった問題があります。

GitHubで使われているシンタックスハイライトの処理系はPygments( http://pygments.org/ )ですので、そちら単体で試してみて、それで同様の問題があるようならPygmentsの問題ということになります。

Pygmentsのリポジトリをクローンして、pygmentize というスクリプトが単体実行用のコマンドなので、次のようにします。

$ cat ../sample_in.awk
END { intval = 1.1; print int(intval) }
$ ./pygmentize -o ../sample_out.raw ../sample_in.awk

コマンドラインオプションで、入力を解析するレキシカルアナライザや、出力形式のフォーマッタを指定することもできますが、拡張子で決めさせたほうが楽でしょう。この例の場合、次のような出力が得られました。

$ cat ../sample_out.raw
Token.Name.Other        u'END'
Token.Text      u' '
Token.Punctuation       u'{'
Token.Text      u' '
Token.Text      u''
Token.Operator  u'in'
Token.Text      u''
Token.Name.Other        u'tval'
Token.Text      u' '
Token.Operator  u'='
Token.Text      u' '
Token.Text      u''
Token.Literal.Number.Float      u'1.1'
Token.Punctuation       u';'
Token.Text      u' '
Token.Text      u''
Token.Keyword.Reserved  u'print'
Token.Text      u' '
Token.Operator  u'in'
Token.Text      u''
Token.Name.Other        u't'
Token.Punctuation       u'('
Token.Text      u''
Token.Operator  u'in'
Token.Text      u''
Token.Name.Other        u'tval'
Token.Punctuation       u')'
Token.Text      u' '
Token.Punctuation       u'}'
Token.Text      u'\n'

やはり"in"の部分の認識のされかたがおかしい、というのが見えますので、GitHubでの不具合の原因はPygmentsだとわかりました。長くなるので省きますが、elseについても同様に確認できます。

あとは、Pygmentsのソースコードを読んで修正してプルリクエストを送るだけです。

以上のような私の例の場合は「elseをキーワードの列挙に追加する」「パターン中の in の直後に、単語の切れ目にマッチする \b を入れる」という修正になりました(具体的にはプルリクエスト https://bitbucket.org/birkenfeld/pygments-main/pull-request/310/fix-awk-lexer-add-else-keyword-and-fix/diff を参照)。

というわけで、GitHubの話として始まったはずが、Bitbucketにプルリクを送った話として終わることになりますが、とりあえず私のプルリクエストはマージされましたので、GitHubのサーバのPygmentsに反映され次第、Awkシンタックスハイライトは改善されるはずです。

まとめ

  • GitHubシンタックスハイライトはPygmentsで行われている
  • Pygments単体でのレキシカルアナライザのチェック方法
  • 改善が必要ならPygmentsのBitbucketにプルリク