Blogger:SyntaxHighlighterにコピペしたタブインデントをスペースインデントに置換する

2017-11-03

旧ブログ

t f B! P L
タブでインデントしたコードをこのブログのSyntaxHighlighterにコピペしたもののインデントがおかしくなっていることに気がつきました。とりあえずブラウザに表示するときにタブだった部分を4個のスペースに置換する小手先の対応で済ませることにしました。

Bloggerに保存するとタブは1つの半角スペースに置換される


Eclipse: PyDevメモ: Mixed Indentation: Spaces foundへの対応で、PyDevではReplace tabs with spaces when typing?のチェックを外してタブをスペースに置換しないようにしました。

そのためそれ以後のPythonのコードはすべてタブでのインデントに統一されています。


しかしこのタブインデントされたコードをこのブログにコピペしてSyntaxHighlighterで表示させるとインデントが小さくなっていました。

タブが縮小されて表示されているだけと思っていたのですが、そうではありませんでした。

ブログからPyDevにコードをコピペしてみるとタブが半角スペースに置換されていることに気が付きました。

タブが4個のスペースに置換されていれば問題なかったのですが、タブは1個のスペースに置換されているので、そのままではコードを動かすことはできませんでした。

Bloggerでは記事を保存すると1個のタブは1個のスペースに置換される仕様になっているようでした。

しかし、保存する前のプレビュー画面ではSyntaxHighlighterで設定した通り1個のタブは4個のスペースに置換されて表示されるのですが、1回保存してしまうと1個のスペースに置換されてしまうのでした。

SyntaxHighlighterではPythonのインデントはpy spacesというクラスになっている


PyDevの設定をタブをスペースに置換する設定に戻すことも考えましたが、またMixed Indentationと戦うことになるので、Bloggerで表示されるたびに1個のスペースを4個のスペースに置換してしまうことにしました。


SyntaxHighlighterではPythonのインデントはpy spacesというクラスになっているので、これは簡単にできそうでした。

SyntaxHighlighterでPythonのタブインデントを4個のスペースに置換して表示する

<script>
window.onload = function(){
    elems = document.getElementsByClassName("py spaces")
    for(i in elems){
        elems[i].innerText = elems[i].innerText.repeat(4)
}};
</script>
これで一応解決しました。

ページの描画が完了したあとに、py spacesクラスの要素をすべて取得して、その文字列を4回繰り返してまたもとの要素に代入しています。

インデントを置換したいのはEclipse: PyDevメモ: Mixed Indentation: Spaces foundへの対応以降の記事のものだけなので、記事のHTMLにこのスクリプトを貼り付けることにしました。

for-in文でdocument.getElementsByClassName()の戻り値をinにすると要素ではなくて、インデックスが返ってきました。
<script>
window.onload = function(){
    document.querySelectorAll(".py.spaces").forEach(function(e){
        e.innerText = e.innerText.repeat(4)
})};
</script>
結局forEach()を使ったこの方法を採用することにしました。

document.getElementsByClassName()とdocument.querySelectorAll()ではセレクタの指定方法が異なりますね。

(2017.11.4追記。window.onloadでは明らかに遅延実行になるので、DOMContentLoadedにしました。
<script>
  document.addEventListener("DOMContentLoaded", function(event){
        document.querySelectorAll(".py.spaces").forEach(function(e){
        e.innerText = e.innerText.repeat(4)})
  });
</script>
これでだいたい違和感なく表示されるようになりました。)

参考にしたサイト


【JavaScript入門】「forEach文」の使い方を基本から応用まで徹底解説! | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト
JavaScriptのforEach文の解説。

javascript - JS: iterating over result of getElementsByClassName using Array.forEach - Stack Overflow
このQ&Aを読んでdocument.querySelectorAll()を使うことにしました。

 DOMContentLoaded - Web 技術のリファレンス | MDN
 これが使えるのならwindow.onloadより表示が速くなります。

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ