[Blogger] コピーボタン付き highlight.js の導入方法 (Version 2) - 高速化とマイナー言語対応 -

Blogger

highlight.js with copy button version 2

この記事では、以前このブログで掲載したBloggerへコピーボタン付きhighlight.jsを導入する方法の改良版を紹介します。コピーボタンを工夫してページ読み込みの高速化を実現した他、インライン化によってCDN呼び出しではできない言語にも対応しています。

highlight.jsのインライン化は導入手順が少し複雑になるので、CDNを使う場合をまず紹介し、その後でインライン化に進みます。

以前の記事はこちらです。使っている仕組みが少し異なり、これはこれで価値があると思うので残しておきます。

改良点

冒頭でも触れましたが、改良点についてまとめておきます。

  1. コピーボタンの動作に使っていた外部ライブラリ"clipboard.js"を削除して軽量化 ← コードを工夫したら使わなくても良くなりました
  2. コピーボタンを押した時の表示を"Copied!"から"Copied to clipboard!"に変更 ← "Copy"から"Copied!"だと変化が少なくて分かりづらかったので…
  3. インライン化によって主要言語以外にも対応 ← ハイライトしたい言語を自分で選んでダウンロードしたものをHTML編集画面から導入します

コピペ用コード(CDN使用)

まず、CDNを使用する場合のHTMLコードです。導入自体はコピペ1発で完了します(その後、スタイルを好みに合わせて変更してください)。

HTML編集画面で、以下のコードを</body>の上に置いてください。jQueryを導入済みの方は改めてjQueryを入れる必要はありません。highlight.jsを導入したいという方は既にコードをいろいろいじっていると思うので、HTML編集の基本的なやり方は省略します。

    <!-- jQuery -->
    <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'/>
    
    <!-- [START] Highlight.js -->
    <link href='//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/styles/foundation.min.css' rel='stylesheet'/>
    <script src='//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/highlight.min.js'/>
    <script>hljs.initHighlightingOnLoad();</script>
    <style>
      .hljs{
      	font-size: 15px;
        max-height:500px;
        background:#f1f8ff;
        font-family: Consolas, Menlo, sans-serif;
      }
      .code-copy{
      	position:relative;
        margin:1em 0;
      }
      pre::before {
        content: attr(title);
        line-height: 1;
        padding: .3em .5em .3em .5em;
        margin: 0 0 0 0;
        background: #f1f8ff;
        color: #000;
      	font-size: 16px;
        font-family: Consolas, Menlo, sans-serif;
      }
      .code-copy-btn{
      	position:absolute;
      	right:0;
        top:0;
        padding: .3em;
      	background:#779cff;
      	color:#fff;
        border:0;
        border-radius:5px;
      	font-size: 16px;
        font-family: Consolas, Menlo, sans-serif;
      }
      .code-copy-btn:hover{
      	cursor:pointer;
        opacity:0.9;
      }
    </style>
    <!-- [END] Highlight.js -->
  
  <!-- [START] Code Copy Button -->
  <script defer='defer'>
  //<![CDATA[
    $(function(){
      $('.code-copy-btn').click(function(){
	    var codeText = $(this).siblings().text();
      	var $textarea = $('<textarea/>');
      	$textarea.text(codeText);
      	$(this).append($textarea);
      	$textarea.select();
        document.execCommand('copy');
        $textarea.remove();
      	$(this).text("Copied to clipboard!"); //Change text
        //Restore original text after 2s
        setTimeout(function(){
          $('.code-copy-btn').text("Copy");
        },2000);
      });
    });
  //]]>
  </script>
  <!-- [END] Code Copy Button -->  

これで導入は完了です!highlight.jsの使い方は以前の記事で説明した通りですが、この記事にも再掲します。その後、コードの説明とインライン化に進みます。

highlight.jsの使い方

highlight.jsを実際に使うためにはコードのまとまりごとに2ステップの作業が必要です。これがちょっと手間なので、楽するための便利ツールも紹介します。

コードのタグをエスケープする

 たとえば<script>タグをそのままHTMLに書くと、scriptを実行しようとしてしまいます。これを文字として表示させるには、"<" を "&lt;" に、">" を "&gt;" にというふうにタグを変換する必要があります。これをエスケープと言います。

前後にタグをつける

エスケープしたコードの前後に、highlight.js用とコピーボタン用のタグをつける必要があります。
前のタグは以下の通りです。

<div class="code-copy">
  <button class="code-copy-btn" title="Copy Text">Copy</button>
  <pre title="HTML"><code class="html">  

buttonタグがコピーボタンです。不要ならこれを消します。

codeタグのclass属性に言語名を書くと、その言語に合わせてハイライトしてくれます(なくても自動判別してくれます)。

preタグのtitleは、最初に載せたCSSの部分でコード左上に表示するように設定しています。必須ではありません。文字色や背景色はスタイルに合わせてください。

後のタグはただの閉じタグです。

  </code></pre>
</div>  

こうしてできたHTMLコードを記事内に置けば、あとはhighlight.jsが勝手にハイライトしてくれて、コピーボタンも出ます。

便利ツール - HTML generator -

「タグをエスケープする」「前後タグをつける」を毎回手でやっていると大変ですよね…。そこで、これらを一発でやってくれる便利ツールを作りました。タイトルやボタンの有無も使い分けられます。こちらで公開しているので、ご自由にお使いください。インストール不要、Webページ上ですぐに使えます。

コードの説明

インライン化する前に導入したコードの理解が必要だと思うので、まず説明します。もう理解できたという方は読み飛ばしてOKです。

CDN呼び出し

最初の部分は、CDNを呼び出しています。

    <!-- jQuery -->
    <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'/>
    
    <!-- [START] Highlight.js -->
    <link href='//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/styles/foundation.min.css' rel='stylesheet'/>
    <script src='//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/highlight.min.js'/>
    <script>hljs.initHighlightingOnLoad();</script>
  

上から順に

  1. jquery.min.js... JavaScriptを簡単に記述できる
  2. foundation.min.js... highlight.jsのテーマ(後述)
  3. highlight.min.js... highlight.js本体
  4. hljs.initHighlightingOnLoad()... highlight.jsの初期化処理

です。jQueryは、もし他で既に呼び出している場合は不要なので、削除してください。また、「コピーボタンはいらない」という場合も不要です。

ちなみに、highlight.jsのCDNでは38の主要言語をハイライトできます。詳しくはこちら↓

Getting highlight.js

その他の言語をハイライトしたり、不要な言語を省いたり、文字色などを微調整したい場合は、上記サイトで言語を選んでファイルをダウンロードし、HTML編集画面でコードを貼り付ける必要があります。これがいわゆる「インライン化」です。後で説明します。

テーマ選び

highlight.jsは、94のテーマから好きな見た目のものを選ぶことができます。当ブログでは、"foundation"を使用しています。テーマの変更は、

<link href='//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/styles/foundation.min.css' rel='stylesheet'/>  

この"foundation"の部分を好きなテーマ名に置き換えればできます。以下のサイトで見た目を確認できるので、探してみてください。

highlight.js demo

ただしひとつ注意があります。もしテーマ名にスペースがあるものを選んだ場合、スペースではなくハイフン"-"に置き換える必要があります。例えば"An Old Hope"だと、"an-old-hope"という風に。でも"A 11 Y Dark"は"a11y-dark"のようです。たぶんこちらのページにあるものと同じ名前にしておけば良いはず↓
highlight.js/src/styles at master · highlightjs/highlight.js · GitHub

インライン化する場合は、全テーマのCSSが付いてくるので、好きなものを自分のスタイルシートに置けばOKです。後述します。

CSS

CDNの下の<style>タグ以下は、自分で追加したCSSです。フォントや背景色を変えたり、コピーボタンのデザインと配置を決めたり、pre::beforeの部分でタイトルを表示させたりしています。自由に編集可能です。

コピーボタンの動作

コピーボタンの動作はjQueryを使って実装しています。以前はclipboard.jsに頼っていたコピー動作を、「仮のtextareaを用意して、そこにテキストを入れて、execCommandでコピーする」という方法で実現しました。コードは少し長くなりましたが、外部ライブラリが減った分、読み込みは速いはずです。

コードのテキストを取得してクリップボードにコピー

	var codeText = $(this).siblings().text();
      	var $textarea = $('<textarea/>');
      	$textarea.text(codeText);
      	$(this).append($textarea);
      	$textarea.select();
        document.execCommand('copy');
        $textarea.remove();
  

ボタンの文字を"Copy"から"Copied to clipboard!"に変え、2秒後に元に戻す

      	  $(this).text("Copied to clipboard!"); //Change text
          //Restore original text after 2s
          setTimeout(function(){
            $('.code-copy-btn').text("Copy");
          },2000);
  

以上です!

インライン化

いよいよ、インライン化に入ります。インライン化によって主要言語以外に対応でき、さらにCDN呼び出しが無くなるので軽量化も期待できます。「ふじろじっく」さんがこの方法で導入していたので、参考にさせていただきました。行番号を付けるカスタマイズも紹介されています。

言語を選んでダウンロード

以下のページへ行き、"Custom package"という項目でハイライトしたい言語にチェックをして下の"Download"ボタンを押します。

Getting highlight.js

Zipファイルがダウンロードされるので、解凍します。

highlight.js本体のコードをHTMLに挿入

フォルダ内にある"highlight.pack.js"を右クリックして「編集」で開くとhighlight.js本体のコードが表示されるので、これを全コピーします。BloggerのHTML編集画面を開き、先ほど説明したCDN "highlight.min.js"の下あたりに置きます。400行くらいあります。

ここで、scriptタグとCDATAで囲まないと保存時エラーになるので注意してください。以下のようにします。

  <script defer='defer'>
  //<![CDATA[
    ---highlight.js のコードをここに置く---
  //]]>
  </script>
  <script defer='defer'>hljs.initHighlightingOnLoad();</script>
  

これで保存できればOKです。CDNの"highlight.min.js"は不要なので削除かコメントアウトしてください。

styleコードをHTMLに挿入

同じフォルダにstyleフォルダがあるので、その中から好みのテーマを探して、同様に右クリックして「編集」で開いてコードをコピーし、styleタグの中に置いてください。スタイルシートのCDNも不要になるので、削除かコメントアウトします。

好みのテーマは、下のページから見つけてください。

highlight.js demo

これでインライン化完了です!お疲れさまでした。

おわりに

Bloggerへコピーボタン付きhighlight.jsを導入する方法の改良版として、コードの工夫とインライン化によってCDN呼び出しを削減したバージョン2を紹介しました。ページ読み込みの高速化につながるだけでなく、CDNではできなかった主要言語以外の対応もこれでできます。個人的にはVBScriptを追加できて満足です。

改造リストも随時更新しています。

About Me

My photo
かもとしゃけ。聖書と音楽。
Follow Me?

Labels

Blogger (14) Other (3) Studio One (1) Tool (6)

Table of Contents