Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

QiitaのPythonコードブロックのシンタックスハイライトの構文の色が条件により変わる現象について

QiitaのPythonコードブロックにおいて、シンタックスハイライトが書き方によって構文の色が変わる現象に気づきました。この変化がコードの可読性に影響を及ぼす可能性があると感じており、意見交換したいと思っております。

相談したい点

  • この色の変動は、Qiitaのエディタ仕様に基づくものでしょうか?
  • 他のエディタでも同様の現象が発生するのでしょうか?異なるエディタでの経験がある方の意見を聞きたいです。

シンタックスハイライトの色が条件により変わる現象

この現象は、括弧の有無に基づいていると考えています。

例えば、for文やif文の例を挙げると以下のようになります。

for文の例
for i, j in zip(lists):
    pass
for (i, j) in zip(lists):
    pass
if文の例
if i:
    pass
if (i):
    pass

私の環境での表示画面のスクリーンショット
image.png

この現象における可読性への影響

個人的には、特定の構文が常に同一の色で表示されることがコードの可読性を高めると考えています。しかし、QiitaのPythonコードブロックで遭遇するシンタックスハイライトの変動は、この一貫性を損ねる可能性があります。たとえば、以下のサンプルコードのように、elif文に2色が使われて表示されることがあります。

elif文に二つの色使われる例
if a == b:
    pass
elif abs(a - b) == 1:
    print("adjacent")
elif (a - b == 2) or (a - b == 2):
    pass
elif (a - b) % 1000 == 0:
    pass
elif a // 1000 == 3:
    pass
elif (a + b) / (a - b) == 1:
    pass
else:
    pass

私の環境での表示画面のスクリーンショット
image.png

この問題に関して何か情報をお持ちの方、または似たような経験をされた方は、ぜひご意見をお聞かせください。共有していただけると非常に助かります。

表示環境

  • MacBook Pro M1
  • Mac OS 14.5
  • Google Chrome Version 109.0.5414.119 (Official Build) (arm64)
2

この色の変動は、Qiitaのエディタ仕様に基づくものでしょうか?

そうです。 Qiita のエディタが採用しているシンタックスハイライトライブラリである Rouge の挙動(バグ)です。

Qiita MarkdownのシンタックスハイライトにはRougeを利用しており

# Qiita::Markdown::Filters::SyntaxHighlight::Highlighter#highlight
          def highlight(language)
            Rouge.highlight(code, language, DEFAULT_OPTION)
          end

Rouge がそのコードをどう解釈しているかは rougify debug コマンドで確認できます。

% gem install rouge

% cat if_noparen.py
if True:
    pass

% rougify debug if_noparen.py
lexer: python
stack: [:root]
stream: "if True:\n    pass\n\ni"
  trying: #<Rule /\n+/m>
# 中略
  trying: #<Rule /(?<!\.)(?-mix:[[:alpha:]_][[:alnum:]_]*)/>
    got: "if"
    yielding: Keyword, "if"
# 後略

% cat if_paren.py
if (True):
    pass

% rougify debug if_paren.py
lexer: python
stack: [:root]
stream: "if (True):\n    pass\n"
  trying: #<Rule /\n+/m>
# 中略
  trying: #<Rule /([a-z_]\w*)[ \t]*(?=(\(.*\)))/m>
    got: "if "
    yielding: Name.Function, "if "
# 後略

カッコがある場合、 if が誤って関数としてパースされていることがわかります。


他のエディタでも同様の現象が発生するのでしょうか?

エディタが採用するシンタックスハイライトライブラリによりますが、(Python のif や for の例に限らず)実際の構文とは違う色づけがされることはあります。

1Like

@uasiさん、早急にご教授くださりありがとうございます。Qiitaのエディタが採用しているRougeシンタックスハイライトライブラリの挙動によって、特定の構文が誤って異なる色で表示されることがあるようですね。大変勉強になりました。

0Like

Your answer might help someone💌