純規の暇人趣味ブログ

首を突っ込んで足を洗う

JavaScriptを利用してpreタグをインデント出来る様にする

      2016/04/15    HimaJyun

preタグは改行や空白をそのままに表示してくれる便利なタグです。
しかし、それ故にpreタグに含まれる要素をインデントする事が出来ず、入り組んだ要素内にあるpreタグのメンテナンス性が低下してしまいます。

そのため、JavaScriptを利用して、preタグ内でも問題無くインデントする方法を考えてみました

preタグもインデントしたい!!

普通は必要ないのですが「ソースコード」やら「測定結果」やらの既に整形されてあるテキストをペタッと貼り付けちゃうと色々崩壊&バーストして悲惨な事になります。

そこで、多くの場合は<pre>なる要素を利用してペタッと貼り付ける事が多いです。
(ソースコードは<code>でやるのが正しいのではないかとは思いますが……)

ご存知でしょうが、preを使うと改行や空白がそのまま反映されます。

pre内でインデント出来ない

preは改行や空白が「そのまま」反映されます、それ故に発生する問題もあります。
そう、「インデント出来ない」のです。

例えば、以下の様にpreで表されたソースコードがあると致しましょう……


<div>

<pre>
package jp.jyn.sample;

public class sample {
  public static void main(String[] args) {
    System.out.println("テスト");
  }
}
</pre>
</div>

以下の様に表示されます。
javascript-pre-indent-001

とは言え、これだと階層が分かりづらく、メンテナンス性が悪いのでインデントしたとします。

<div>
  <pre>
    package jp.jyn.sample;

    public class sample {
     public static void main(String[] args) {
       System.out.println("テスト");
     }
    }
  </pre>
</div>

もうお分かりでしょうが、以下の様になってしまいます。
javascript-pre-indent-002

分かりづらいので反転させてみましょうか
javascript-pre-indent-003

そうです、インデントまで表示されてしまっているのです。

今回の例の場合はdivが1個なのでインデントしなくても大した影響はないですが、これが<body><div id="main"><div id="article"><div id="hogehoge"><pre>とかの中だと悲惨な事になりますね。

だったらJavaScriptで書き換えちまえ

きょうびJavaScriptを切っている人間なんてきっと居ないでしょう……
セキュリティ対策で切っているとしたら……そいつが切るべきはJava(Scriptじゃない方)とFlashとSilverlightですね……

そんな事はどうでも良いでしょう、インデントまで表示されてしまうのならば、表示されてしまうインデント分をJavaScriptで書き換えて削除してしまえば良いのです。

と言う訳で僕が考えたのは以下の通り

<script>
// pre内のタブ文字削除(タブインデントが出来る)
window.addEventListener("DOMContentLoaded", function(){
  // preを取得
  var pres = document.getElementsByTagName("pre");
  // 反復処理
  for (var i = 0; i < pres.length; i++){
    // タブ文字を消す
    pres[i].firstChild.data = pres[i].firstChild.data.replace(/^\t+/gm,"");
  }
},false);
</script>

使い方

先程のソースコードを好きな所(</body>の上がおススメ)に入れます、これでpreタグをインデントが出来る様になります。

問題点としては、インデントはスペースではなく、タブ文字でインデントしないと行けない事ですかね。
ただ、これは「replace(/^\t+/gm,"")」を「replace(/^ +/gm,"")」とかにして頂ければ行けます。

また、全てのpreを対象にしてしまうのが気に入らない場合は「getElementsByTagName("pre")」を「getElementsByClassName("hoge")」などとすれば「class="hoge"」が付いたpreのみを対象に出来ます。(hogeはお好きな様にどうぞ)

要は、ページをロードした際にpreタグの中身を見て、そこからタブ文字を消し去っているだけですね。

これが必要となる様な状況が限られ過ぎているためイマイチ価値の方が見出せませんが、もしpreも綺麗に整えてメンテナンス性の高いpreを設置したければぜひご利用下さいませ……

 - Web制作