プログラマ・アゲイン blog

還暦を過ぎたけどプログラマ復帰を目指してブログ始めました

ソースコードを貼り付けるボックスを作成 (1)

ソースコード貼り付け用ボックス作成

プログラミングのブログを書こうと思うと、どうしてもブログの中にソースコードを記述する必要が出てきます。しかし、単純に記述したのでは、それがソースコードだということが判りにくくなります。

はてなブログでは、はてな記法モードでソースコードを簡単に張り付けて色付けまでしてくれる機能があるので、それを使うのが一番だとは思います。しかし、見たままモードで編集していたものをはてな記法モードに変更しようとすると、「編集画面をリセットするため、作成中の本文は消去されます。この操作は元に戻せません。」といわれてしまいます。だったら最初からはてな記法モードで編集しろよ、ということではあるのですが。。。(-_-;)

そこで、そのままモードで編集してブログの中にソースコードを記述するために、自分なりのソースコードの貼り付け用ボックスを作ってみました。

 

 単純なボックス

まずは、以前のブログ JavaScript①でも使用した、単純なボックスを作成しました。

JavaScript①:ブログの目次を表示/非表示にしたらセキュリティに引っ掛かりました - プログラマ・アゲイン blog

どこかのブログを参考にさせていただいたのですが、改めて検索すると見つけられません。m_ _m

<!DOCTYPE html>
<html><body><h1 id="title">タイトル</h1>
  <p>これは<b>パラグラフ</b>です</p>
</body></html>

「all select」のボタンや左上にソースタイプを表示するボックスが出ていますが、これは次の拡張でJavaScriptを追加したせいで出てきてますので、今は無視してください。

このボックスは、以下の<pre>...</pre>タグで記述しています。

<pre class="code" style="margin: 0px 0px 10px; padding: 20px; border: 1px solid #eceef1; overflow: auto; font-family: Monaco, Consolas, 'Courier New', Courier, monospace, sans-serif; font-size: 1em; white-space: pre;" data-unlink="" data-lang="">
ここにソースコードを記述
</pre>

当然、ソースコードエスケープシーケンスで記述する必要があるので、以下のサイトなどで文字変換をしたものを貼り付けます。

tech-unlimited.com

ところが、HTML編集で<pre>...</pre>タグを作成しておき、見たまま編集でソースコードをそのままボックスの中に張り付けると、自動的にエスケープシーケンスしてくれています。はてなブログの方でやってくれるようです。

 

行番号&背景&全選択

もう少し、かっこよくソースコードを表示したいので、以下のブログを参考にさせていただきました。

kurokinomizuiwa.hatenablog.com

 Scriptを「デザイン」→「カスタマイズ」→「フッタ」に、CSSを「デザイン」→「カスタマイズ」→「CSS」にコピー&ペーストするだけです。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>JavaScriptプログラミング</title>
  </head>
  <body>
    <h1 id="title">
      タイトル
    </h1>
    <p>
      これは<b>パラグラフ</b>です
    </p>
  </body> 
</html>

ただ、これでも良いのですが、以下の点をカスタマイズしたいと思いました。

  1. ソースコードの行間を詰めたい
  2. ソースタイプのブロックをソースコードのブロックより少し上に出したい
  3. ソースコードのブロックとコンソールのブロックは明確にスタイルを分けたい
  4. 「all select」の表示をソースコードのブロックだけにしたい
  5. ソースコードのブロックから外れたら「all select」を消したい
  • etc.

そこで、単純にコピー&ペーストしたScriptとCSSの内容を変更したものを、新規に作成することにしました。

 

ScriptとCSSのカスタマイズ

まずはカスタマイズの概要です。

それまでのScriptとCSS

まず、それまでのScriptとCSSの内容を確認することから始めました。

コピー&ペーストしたScriptとCSSは、ちょっと長いですが以下のものです。

<script>
//ソースコードの行をdivタブで囲む
var codeBlocks = document.getElementsByClassName('code');
[].forEach.call(codeBlocks, function(e) {
  if (!/lang/.test(e.className)) {
    return;
  }
  var lines = e.innerHTML.split(/\n/);
  var codeBlock = "";
  lines.forEach(function(line){
    if(line != ""){
      codeBlock += '<div class="code-line">' + line + '</div>' 
    }
  })
  e.innerHTML = codeBlock;
});
</script>
<script defer>
//ソースコードを全選択するボタンの処理
(function(d){
  if(!window.getSelection){
    return
  }
  var btn = d.createElement("button")
  btn.id = "selectPre"
  btn.textContent = "all select"
  btn.addEventListener("click", selectPre, false)
  function selectPre(){
    var sel = window.getSelection()
    var pre = this.parentNode
    sel.selectAllChildren(pre)
    sel.extend(pre, pre.childNodes.length-1)
  }
  var pres = d.getElementsByTagName("pre")
  for(var i=pres.length; i--;){
    pres[i].addEventListener("mouseover", addBtn, false)
  }
  function addBtn(e){
    if(this === addBtn.ele) return // not to addBtn if already
    this.appendChild(btn)
    return addBtn.ele = this
  }
})(document)
</script>
/* ソースコード・ブロック位置は相対 */
pre {
  position: relative;
  border-radius: 10px;
}
/*code-lineクラスの数でカウント*/
.code-line {
  counter-increment: linenumber;
}
/*偶数行のみ背景色を適用*/
.code-line:nth-child(even){
  background-color: #eee;
}
/*行番号を擬似要素として表示*/
.code-line::before {
  content: counter(linenumber);
  display: inline-block;
  color: #ccc;
  text-align: right;
  width: 35px;
  padding-right: 15px;
}
pre.code {
  padding: 30px 0 15px 0;
  border: 2px solid #ccc; /*追加:コード表示部分の枠設定*/
  background: #f8f8f8; /*追加:コード表示部分の背景色*/
  position: relative; /*追加*/
}
/*コードブロックに言語名を表示*/
pre.code:before {
  content: attr(data-lang);
  display: inline-block;
  background: #ccc; /*カラーコード変更*/
  color: #666;
  padding: 3px 5px;
  position: absolute;
  margin-top: -30px; /*表示位置を調整*/
  border-radius: 6px; 
}
/* ソースコード全コピー用のボタン表示
#selectPre{
  position: absolute;
  top: 0;
  right: 0;
  border: none;
  margin: 0px 0px 10px 20px;
  padding: 2px 3px;
  font-family: consolas
}

JavaScriptの1行目~17行目とCSSの6行目~39行目の部分がソースコードのブロック用であり、JavaScriptの18行目~44行目とCSSの40行目~49行目の部分が全選択のボタン用です。

なお、ソースコードを全選択するボタンの処理(Script)部分は、新しいものに書き換えたので、現時点でのScriptは上記と変わっています。したがって、動きも変わっています。

 

目標とするボックス

このScriptとCSSを書き換えて、以下のような単純なコンソール・コマンド貼り付け用と、ソースコード貼り付け用ボックスを作成しました。小さくコンパクトな感じになりました。

コンソール・コマンド用
$ npm install --global @js-primer/local-server

 

ソースコード
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>JavaScriptプログラミング</title>
  </head>
  <body>
    <h1 id="title">
      タイトル
    </h1>
    <p>
      これは<b>パラグラフ</b>です
    </p>
  </body> 
</html>

 

すみません。このページは長くなったので、この辺で一休みしようと思います。

どのようなScriptとCSSを作成したかについては、次のブログで書きたいと思います。m(__)m

[次のブログへ続く]