HTMLの末尾で読み込むことで、DOMをいじって各種機能を提供するJavaScriptであるpostprocess.jsの一部です。
GitHubにも置いてあります。リポジトリは「※にマウスオーバーで脚注を表示する」と共有しています。
https://github.com/kmaebashi/postprocess
HTMLの終わりの方、</body>の直前あたりで、以下のように読み込む使い方を想定しています。(前略) <script src="./postprocess.js"></script> </body> </html>
postprocess.jsは、上記<script>要素を読み込んだ時点で実行され、かつ、その時点で本文のDOMが構築済みであることを想定しているため、必ずページの末尾で読み込まなければいけません。
HTML内にソースコード等を載せる際、linenumberクラスを付与した<pre>要素として記述すると、行番号を付けてくれる機能です。この「コピペで使おう! ライブラリ」のページに貼ってあるソースはすべてこれで行番号を付けています。
このWebサイトでは、以前は、ソースを貼るときは、大昔に作った自作のCプログラムでHTML内に直接行番号を含めていました(たとえばここに実例があります)。しかし、この方法だと、Webページからソースをコピペしようとすると行番号も付いてきてしまいます。このプログラムを使えば、行番号抜きでのコピペが可能です。
<pre class=linenumber> #include <stdio.h> int main(int argc, char **argv) { printf("hello, world.\n"); return 0; } </pre>
このように書くと、以下のように行番号が振られます。
#include <stdio.h> int main(int argc, char **argv) { printf("hello, world.\n"); return 0; }
<pre>内に記述するコードは、HTMLのエスケープが事前に行われている前提です(上記hello, worldの「#include <stdio.h>」を参照のこと)。
これで生成されるコードブロックは、1行2列の<table>要素であり、左の<td>に行番号が、右の<td>にソースが入れられています。以下のclass属性が付与されているので、見た目はCSSでいじってください。
要素 | class属性 |
---|---|
table全体 | linenumbertable |
左のpre | linenumber-left-td |
右のpre | linenumber-right-td |
postprocess.js(この機能分だけ抜粋)
"use strict;" const lineNumberPreArray = document.querySelectorAll("pre.linenumber"); for (codePre of lineNumberPreArray) { const tableElem = document.createElement("table"); tableElem.classList.add("linenumbertable"); const trElem = document.createElement("tr"); tableElem.appendChild(trElem); const leftTdElem = document.createElement("td"); leftTdElem.classList.add("linenumber-left-td"); trElem.appendChild(leftTdElem); const leftPreElem = document.createElement("pre"); leftTdElem.appendChild(leftPreElem); const rightTdElem = document.createElement("td"); rightTdElem.classList.add("linenumber-right-td"); trElem.appendChild(rightTdElem); const rightPreElem = document.createElement("pre"); rightTdElem.appendChild(rightPreElem); // 文字列を\nで区切ると最後の\nの分だけ1行多くなるので1削っている。 const lineCount = codePre.innerText.split("\n").length - 1; let lineNumbers = ""; for (let i = 0; i < lineCount; i++) { lineNumbers += ("" + (i+1)).padStart(3) + ":\n"; } leftPreElem.innerText = lineNumbers; rightPreElem.innerHTML = codePre.innerHTML; codePre.parentElement.replaceChild(tableElem, codePre); }
3行目でlinenumberクラスの<pre>をかき集め、それらすべてについて(4行目のループ)、中に1行2列の<table>要素を作って、左の<td>の中の<pre>(leftPre)には必要な数だけ行番号を突っ込み(20~26行目)、右の<td>の中の<pre>(rightPre)には元の<pre>の中身(ソース)を突っ込んでいます。
いまどき、コードを貼るなら、<pre>だけでなく<code>でも囲むのが普通のような気はしますが、それをやると行数の算出が変わってくるのと、うちのページでは見た目同じなのでやっていません。
このページと同等の見た目になるCSSも貼っておきます。
table.linenumbertable { margin-left: 2em; background: #ccffff; border-right: solid 1px #99cccc; border-bottom: solid 1px #99cccc; margin-top: 0px; } table.linenumbertable pre { margin-top: 0px; margin-bottom: 0px; } td.linenumber-left-td { padding-top: 5px; padding-bottom: 5px; padding-right: 3px; border: none; color: #0000ff; } td.linenumber-right-td { padding-top: 5px; padding-bottom: 5px; padding-right: 30px; border: none; }
公開日: 2024/01/06
不具合等ありましたら、掲示板にご連絡願います。