問題
2020年9月現在、AtCoderの提出済みコードのシンタックスハイライトは言語に応じたハイライトを行なっていません。
その結果、キーワードが正しく色付けされなかったり、識別子にプライムを使える言語 (HaskellやOCaml) でハイライトが壊れる、というような現象が起こっています。例えば この提出 の44行目、 U.foldl'
以降が全部文字列の色になっています。
この問題は1年半前に筆者が原因を特定してchokudaiさんに報告しましたが、なんやかんやでまだ修正されていません。
ただひたすら待っているだけなのもアレなので、ユーザー側でこの問題を修正するUserScriptを作ってみました。Firefox上のGreasemonkeyとChrome上のTampermonkeyで動作確認しています。
作ったもの
GreasemonkeyやTampermonkeyを導入している方はこのURLを踏むとインストールできます:
ソースを読みたい方はこっちです:
https://gist.github.com/minoki/ca14e78062e41112ee3248cf18c9718a
技術的な話
AtCoderのHaskellシンタックスハイライトで識別子中のプライムがおかしい件、完全に理解してしまった。AtCoder側の問題やんけ
— damepo-lab-137-268-271-443.example.com (@mod_poppo) April 1, 2019
まず、現状のAtCoderではcode-prettyを適用する際に言語名を指定していないため、C++のような定番言語であっても正確なハイライトが行われていません(例:stringはC++のキーワードではないのにキーワードと同じ色でハイライトされている)。言語名は<pre>のclassで指定できます(lang-cpp等)
— damepo-lab-137-268-271-443.example.com (@mod_poppo) April 1, 2019
次に、そこまでメジャーではない言語(Haskell等)に正確なハイライトを施すには、その言語用の「extension」を読み込む必要があります。extensionを読み込むには、<script>タグで読み込んでいるrun_prettifier.jsに ?lang=hs 等のオプションをつけます。詳しくは→ https://t.co/DA7m2QSIAZ
— damepo-lab-137-268-271-443.example.com (@mod_poppo) April 1, 2019
この2つを適切に設定すれば、code-prettifyが対応している言語に関して正しくハイライトが行われるはずです。
— damepo-lab-137-268-271-443.example.com (@mod_poppo) April 1, 2019
UserScriptとして実装するにあたり、run_prettifier.js
のURLの末尾に「?lang=hs
」みたいなやつをつけるという選択肢は取れません。なので、自前で必要なスクリプトを読み込んでいます。
言語・処理系名の部分のXPathを見ればわかりますが、AtCoderのサイトのDOM構造の改変に脆弱です。Firefoxのインスペクターからコピってきたらこうなりました。もうちょっと上手い書き方があるとは思いますが、実際に動かなくなってから考えます。
ちなみに、2020年9月現在、code-prettifyの開発は既に終了しているようです(archivedになっている)。AtCoderがシンタックスハイライト方法をcode-prettify以外のもの(あるいはcode-prettifyの適当なfork)に変えない限り、最近の言語機能、例えばC++14のdigit separatorが正しくハイライトされる日は来ないと思われます。