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
不具合等ありましたら、掲示板にご連絡願います。