MENU

JavaScriptサンプルコード

【JavaScript】 preやdiv要素内に行番号を付与する

更新日:2020/06/21

 

このサイトでは、サンプルコードを掲載している記事が多いです。
時々、サンプルコードに行番号を付与した方がいいのではないかと思う時があります。

 

そこでpreやdiv内に行番号を付与する方法をお伝えします。

 

スクリプトコード

 

preやdiv内の行が全て同じ高さのとき、次のコードで各行に行番号を付与できる。

 

JavaScript

 

( lineMax => {
    window.addEventListener( "DOMContentLoaded" , ()=> {
        const content = '.lnumber:before{content:"' + ( () => {
            const buf = [];
            for( let i = 1 ; i <= lineMax ; i ++ ) buf.push( i.toString() );
            return buf;
        })(  ).join( "\\a " ) + '";}';

        const styleTag = document.createElement("style");
        styleTag.innerHTML = content;
        document.getElementsByTagName("head")[0].appendChild(styleTag);
    });
})( 300 );

 

次のCSSも必要。

 

css

 

.lnumber{
        position: relative;
        padding: 0 1em 0 55px;
}
.lnumber p{
        margin: 0;
        padding: 0;
}
.lnumber:before {
        height: 100%;
        width: 50px;
        position: absolute;
        left: 0;
        top: 0;
        word-wrap: break-word;
        overflow: hidden;
        color: green;
        white-space: pre;
        text-align: right;
        background: white;
        color: gray;
        font-family: "arial";
        border-right: 1px solid gray;
        padding: 0 5px 0 0;
        box-sizing: border-box;
}

使い方

 

使い方は、下の例のようにlnumberクラスを付与する。

 

<div style="border:1px solid black;">
<pre class="lnumber">
( lineMax => {
    window.addEventListener( "DOMContentLoaded" , ()=> {
        const content = '.lnumber:before{content:"' + ( () => {
            const buf = [];
            for( let i = 1 ; i <= lineMax ; i ++ ) buf.push( i.toString() );
            return buf;
        })(  ).join( "\\a " ) + '";}';

        const styleTag = document.createElement("style");
        styleTag.innerHTML = content;
        document.getElementsByTagName("head")[0].appendChild(styleTag);
    });
})( 300 );
</pre>
</div>

 

実行すると、次のようにpre要素に行番号が付与されます。

 

<div style="border:1px solid black;">
<pre class="lnumber">
( lineMax => {
    window.addEventListener( "DOMContentLoaded" , ()=> {
        const content = '.lnumber:before{content:"' + ( () => {
            const buf = [];
            for( let i = 1 ; i <= lineMax ; i ++ ) buf.push( i.toString() );
            return buf;
        })(  ).join( "\\a " ) + '";}';

        const styleTag = document.createElement("style");
        styleTag.innerHTML = content;
        document.getElementsByTagName("head")[0].appendChild(styleTag);
    });
})( 300 );
</pre>
</div>

 

div要素でも同じことが可能です。

 

解説

 

疑似要素beforeのcontentに"\a"を指定すると改行します。
その特性を利用して、行番号を付与しています。

 

そのためJavaScriptを使用しなくても、cssで次のように指定すれば表示されます。

 

.lnumber:before {

    content: "1\a 2\a 3\a ・・・・・";
}

 

しかし入力した行数しか表示されません。
数百行に及ぶ行数を表示したい場合、手作業で入力するのは非常に困難です。

 

そこでJavaScriptで動的に、contentの値をセットしています。

もっと簡単に番号を付与できる『Google Code Prettify』

 

Google Code Prettify』は、ソースコードを色分けしてくれるJavaScriptライブラリです。
手軽に行番号が付与されればいいなら、おススメです。

 

使い方

 

次のコードをheadタグ内に記述して、スクリプトを読み込みます。

 

<script async src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>

 

 

行番号を付与したいコードを<pre class="prettyprint linenums"></pre>または<code class="prettyprint linenums"></code>内に記述します。
残念ながら<div></div>は使用できません。

 

Google Code Prettify使用例

 

<pre class="prettyprint linenums">
( lineMax => {
    window.addEventListener( "DOMContentLoaded" , ()=> {
        const content = '.lnumber:before{content:"' + ( () => {
            const buf = [];
            for( let i = 1 ; i <= lineMax ; i ++ ) buf.push( i.toString() );
            return buf;
        })(  ).join( "\\a " ) + '";}';

        const styleTag = document.createElement("style");
        styleTag.innerHTML = content;
        document.getElementsByTagName("head")[0].appendChild(styleTag);
    });
})( 300 );
</pre>

 

実際に表示すると次のようになります。

 

Google Code Prettify 行番号がおかしい

 

cssの調整

 

デフォルトでは5行ごとに番号が振られています。
しかし10行目は、掲載しているサイトのスタイル属性の影響を受けてしまい、0しか見えていません。

 

『Google Code Prettify』は自動で専用のcssファイルを読み込んでくれるのですが、設定が不十分です。

 

そこで独自にcssを追加して調整します。

 

CSS

 

.prettyprint{ /* 枠線 */
  border-left: 5px solid green;
  padding: 0;
}
.prettyprint ol.linenums{
  list-style:none;
  counter-reset: linenums_count;
  overflow: hidden;
  position: relative;
  padding:0;
  margin:0;
}
.prettyprint ol.linenums > li{ /* 表示されるテキスト */
  padding:0 5px 0 50px;  /* 行番号の幅を変更するときは、*/
                                   /* 4つめのpxを調整する */
}
.prettyprint ol.linenums > li:before{ /* 行番号 */
  counter-increment: linenums_count;
  content: counter(linenums_count);
  width: 40px;   /* 行番号の幅 */
  text-align: right;
  display: block;
  position: absolute;
  left: 0;
  border-right: 2px solid #ccc;
  border-top:1px solid #ccc; 
  padding-right:3px;
  background: white;
}

 

CSSを適用すると、次のように表示されます。

 

Google Code Prettify 行番号がおかしい 修正済み

 

注意点

 

『Google Code Prettify』の問題というよりもpreタグを使用するときの注意点ですが、『<』と『>』を使用する場合はエンティティに変換する必要があります。

 

具体的には、次のように書き換えます。

 

『<』→『&lt;』
『>』→『&gt;』

 

僕は最初手作業で書き換えていましたが、面倒に感じてきたのでエンティティをおこなうツールを作成しました。

 

HTMLエンティティ変換ツール

 

HTMLエンティティ変換ツールのデフォルト状態は、スペースを変換してしまいpreタグの意味がなくなってしまうので、次の図のようにオプションを開いて、スペースとタグのチェックを外してください。

 

HTMLエンティティ変換ツール スペースとタグのチェックを外す

 

その後、変換したい文字列エリアにコードを貼り付けると、自動で変換結果が表示されます。

 

クリップボードへコピーを押すとコピーされるので、preタグ内に貼り付ければ完了です。

 

ぜひ使ってみてください。

行番号は必要か?

コードの解説するとき、行番号があると便利ですね。
ただコードを手直して行番号がズレると、記事を見直す必要があります。

 

手間に感じるということもありますが、それよりも修正忘れの方が怖いです。
そのため、行番号を使用しないで解説したほうが無難です。

 

説明に行番号が必要ないとすると、後は読んだ人がどう感じるか考える必要があります。
とはいえ考え方は千差万別なので、アンケートをとって判断するしかないのですが、現実的ではありません。

 

結局は自分がどう思うかで判断することになります。

 

行番号があると、その分だけ表示できる幅が狭くなりコードが見にくくなります。
そのため、僕は今のところ行番号は付与しません。

 

記事を書いたけれど自分は使わないとか…
我ながらひどいですね(反省はしない

記事の内容について

 

こんにちはけーちゃんです。
説明するのって難しいですね。


「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。

そんなときは、ご意見もらえたら嬉しいです。

ご意見はこちら。
https://affi-sapo-sv.com/info.php