pythonのソースコードをブログに投稿した時に、インデントや改行が消えてしまいました。
色々と原因を調査したところ意外な原因が判明しました。
発生した現象
実際に発生した例は次のような感じでした。
競プロのセグメントツリーのコードです。
投稿したいコード
def query(self, left, right):
left += self.size
right += self.size
left_res, right_res = self.default, self.default
while left < right:
if left & 1:
left_res = self.f(left_res, self.dat[left])
left += 1
if right & 1:
right -= 1
right_res = self.f(self.dat[right], right_res)
left >>= 1
right >>= 1
res = self.f(left_res, right_res)
return res
投稿すると表示されたコード
def query(self, left, right):
left += self.size
right += self.size
left_res, right_res = self.default, self.default
while left < right: if left & 1: left_res = self.f(left_res, self.dat[left]) left += 1 if right & 1: right -= 1 right_res = self.f(self.dat[right], right_res) left >>= 1
right >>= 1
res = self.f(left_res, right_res)
return res
「なんかコード短くね?」なんかおかしいぞって感じでしたが、一部のコードでこのように改行やインデントの設定が消えてしまいました。
pythonのコードなのですが、インデントは文法上明確な意味を持っている言語なのでインデントが消えてしまうことは死活問題です。
原因
全てのソースコードの内、この現象が発生したコードは2件でした。
共通しているのは「pythonのコード」、「長いコード」くらいだったのですが、詳しく調査しみると納得の理由が判明しました。
自動整形機能
ワードプレスでは、テキストエディタ→ビジュアルエディタに画面遷移する際に自動整形機能が動きます。
今まで意図しない自動整形はありませんでしたが、今回ははこれが悪さをしていたのです。
演算子「<」と「>」の組合せ
先ほどのコードの一部を抜粋します。
while left < right:
if left & 1:
left_res = self.f(left_res, self.dat[left])
left += 1
if right & 1:
right -= 1
right_res = self.f(self.dat[right], right_res)
left >>= 1
よく見ると(よく見なくても)最初の行と最後の行に、<
>
が記述されています。
ある程度ワードプレスに詳しい人ならピンと来ていると思いますが、ワードプレスではタグを記述する時に使う記号です。
見出しであれば
<h2>ここが見出し</h2>
こんな感じになっているのですが、タグは<tag名></tag名>
で構成されています。
ソースコードを投稿する時はソースコードをテキストエディタに直接貼り付けていたので、ビジュアルエディタに画面遷移する時に自動整形機能が働き<>
の間をタグと勘違いして処理したのでしょう。
そのため<>
の間のみ改行やインデントが消えるという不可解な現象が発生していたのです。
<だけなら<
みたいな感じでエスケープされるのですが、テキストエディタで<~~~~>
見たいな記述をするとタグとみなされて間の文字列は問答無用で改行や空白が削除されるようです。
改行・空白を残してソースコードを投稿する方法
原因は判明したので次はこれを発生させない投稿方法です。
Prismjsを使っているので<code class="language-python"></code>
を追加する必要があったので次のような手順になります。
ソースコードの投稿手順
- いったんPyCharmなどのIDEに貼り付け
- IDEからコピペしてビジュアルエディターに張り付け
- テキストエディタで
<code class="language-python"></code>
を追記
IDEに張り付けたコードをコピーすると<pre></pre>コードで囲まれた状態でビジュアルエディタに貼り付けられます。
<code class="language-python"></code>
の追記が必要だったので、テキストエディタに直接張り付けしていたのがNGだったようです。