Qiitaのコードの左側に選択不可能な行番号を追加するユーザースクリプト

# <i class="fa fa-cubes"></i>　元ネタ

[Qiita > 要望 > コード左側に行番号を表示 - Qiita] <i class="fa fa-external-link"></i>

たまに作りたくなるネタを拝借しています。

最近選択不可のCSSを知ったばかりだったのでタイムリー

まぁ、個人で行番号が見えてn行目～と伝えても通じにくいんですが…

# <i class="fa fa-camera"></i> スクリーンショット

![codenumber.JPG](https://qiita-image-store.s3.amazonaws.com/0/62354/fb538d86-5004-040d-bff9-2f50bbf36298.jpeg)

![codenumberless.JPG](https://qiita-image-store.s3.amazonaws.com/0/62354/c7f30d8d-d5a6-ab40-5f08-f2c12bf84475.jpeg)

![codenumberdrag.JPG](https://qiita-image-store.s3.amazonaws.com/0/62354/7b468e07-820f-a25b-26fb-1b4f0acb34d3.jpeg)


# <i class="fa fa-cogs"></i> 動作検証環境

* Firefox 46
* greasemonkey

[Qiitaのコードにコピーボタンを追加するユーザースクリプト - Qiita]
との併用可能を確認しています。

# <i class="fa fa-code"></i> コード

Gistスクリプトリンク[Qiita_Code_Number.user.js] <i class="fa fa-external-link"></i>

```js:Qiita_Code_Number.user.js
// ==UserScript==
// @name        Qiita Code Number
// @namespace   khsk
// @description コードに選択不可能な行番号を追加する
// @include     http://qiita.com/*/items/*
// @include     https://qiita.com/*/items/*
// @include     http://qiita.com/*/private/*
// @include     https://qiita.com/*/private/*

// @version     1
// @grant       none
// ==/UserScript==

var style = document.createElement('style')
style.type      = 'text/css'
style.innerHTML = `
pre.khsk-codeNumber { 
  float:               left;
  user-select:         none; /* 追加した行番号は選択不可にする */
  -webkit-user-select: none;
  -moz-user-select:    none;
  -ms-user-select:     none;
  -o-user-select:      none;
  overflow-x:          hidden !important; /* スクロールバーはあるのもないのも不自然 */
}
pre.khsk-codeNumber:after {
  clear:               both;
}
`
document.getElementsByTagName('head')[0].appendChild(style)

var codes = document.querySelectorAll('div.highlight pre')
Array.prototype.forEach.call(codes, function(code) {
  var rows = code.innerText.split('\n')
  // 最後に改行が入っていることにより、空要素が生まれるため削除
  rows.pop()
  var length = rows.length
  var numbers = document.createElement('pre')
  numbers.className = 'khsk-codeNumber'
  for (let i = 0; i < length; ++i) {
    // 桁数は3桁までとする
    let number = ('  ' + (i + 1)).slice(-3)
    // Textでは改行が反映されない
    numbers.innerHTML += number + '\n'
  }

  code.parentElement.insertBefore(numbers,code)

})
```

やっていることは単純に`<pre>`を横並びに追加して、コードの行数を数えているだけですね。
ちょっと処理時間がかかる書き方な気がしていますし、配列にするのではなく`'\n'`の数をカウントした方がいいかな？とも思っています。
あとはCSSで選択不可にすれば、コードのみをドラッグで選択できます。

ちょっと左右の余白が多すぎる気もするので、そこはCSSを追加したり。
もしかしたらコード側の`<pre>`のCSSをいじらないとスッキリしないかもしれません。


# 廃案

ハイライトが無効になるためお蔵入り

```js
// ==UserScript==
// @name        Qiita Code Number
// @namespace   khsk
// @description コードに選択不可能な行番号を追加する
// @include     http://qiita.com/*/items/*
// @include     http://qiita.com/*/private/*
// @version     1
// @grant       none
// ==/UserScript==

// 追加した行番号は選択不可にする
var style = document.createElement('style')
style.type      = 'text/css'
style.innerHTML = 'span.khsk-codeNumber { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none;}'

document.getElementsByTagName('head')[0].appendChild(style)

var codes = document.querySelectorAll('div.highlight pre')
Array.prototype.forEach.call(codes, function(code) {
  var rows = code.innerText.split('\n')
  // 最後に改行が入っているので、空要素が生まれるため削除
  rows.pop()
  rows = rows.map((row, index, array)=>{
    // 桁数は3桁までとする
    let number = ('  ' + (index + 1)).slice(-3)
    return '<span class="khsk-codeNumber">' + number + ' </span>' + row
  })
  code.innerHTML = rows.join('\n')
})
```

# 夢想

行番号をクリックしたらその行を選択済みにする、ってコピペに便利そうですけど、`<pre>`じゃ厳しい気がしてならない。
できそう！って教えてもらえれば頑張って調べてみる。

<!-- # 追記

コードはびっしり書かないとダメですね…
自分は```の初めと終わりに空行を挟むことがあるので、それではずれてしまいます…
先頭と末尾の空行は読み飛ばす処理が必要だと思いますので、今後作れば追記して通知します。 -->

[Qiita > 要望 > コード左側に行番号を表示 - Qiita]:http://qiita.com/7of9/items/e65f2f36c817ab965284

[Qiitaのコードにコピーボタンを追加するユーザースクリプト - Qiita]:http://qiita.com/khsk/items/27a80755d883521ecd73

[Qiita_Code_Number.user.js]:https://gist.github.com/khsk/94fed99c690f6dff7634/raw/ea32b5beff42401e40e04f9ba321064292fa4807/Qiita_Code_Number.user.js