eleventy-plugin-code-clipboard

| 4 min read
Author: noboru-kudo noboru-kudoの画像

eleventy-plugin-code-clipboardは、静的サイトジェネレータツールの1つであるeleventy(以下11ty)のカスタムプラグインです。

このプラグインは、マークダウンのコードブロックで生成されたものに対して、クリップボードコピー機能を提供するもので、本サイトでも使用されています。

プラグインは以下の2つの機能で構成されます。

markdown-it カスタムレンダラー

#

11tyのマークダウンパーサー markdown-itのカスタムレンダラーです。
マークダウンで以下のようなコードブロック[1]を記述すると...。

echo "show clipboard button on code block"

このプラグインは、以下のようなHTMLに変換します(見やすくなるように一部改行しています)。

<div style="position: relative">
<pre class="language-shell">
<code id="code-3" class="language-shell">
<span class="token builtin class-name">echo</span> <span class="token string">"show clipboard button on code block"</span>
</code>
</pre>

<button class="code-copy " data-clipboard-target="#code-3"
style="position: absolute; top: 7.5px; right: 6px; cursor: pointer; outline: none; opacity: 0.8;"
title="Copy">

<span>
<span style="font-size: 15px; opacity: 0.8;" class="mdi mdi-content-copy"></span>
</span>
</button>
</div>

オリジナルのHTML(@11ty/eleventy-plugin-syntaxhighlightで生成されたもの)の中に、クリップボードアイコンのボタンを配置します。

11ty shortcode Function(initClipboardJS)

#

11tyではShortcodeと呼ばれるテンプレートエンジンを拡張する仕組みがあります。
このプラグインではinitClipboardJSというShortcodeを提供しています。
これは、HTMLロード時にクリップボードライブラリ(clipboard.js)を初期化し、ボタンクリック時にクリップボードコピーをするソースコードを生成します。
また、クリップボードコピーに成功するとツールチップメッセージ(デフォルトはCopied!)を表示します。

使い方は以下の通りです。下記はNunjucksテンプレートを利用しています(他のテンプレートも使えるはずですが未検証です)。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link href="{{ '/css/style.css' | url }}" rel="stylesheet" />
<body>
{{ content | safe }}

{% initClipboardJS %}
</body>
</html>

{% initClipboardJS %}部分でプラグインのShortcodeを実行しています。

これで静的サイトを生成すると、以下のようにソースコードが生成されます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link href="/css/style.css" rel="stylesheet" />
<body>
<div>
<-- Site Contents... -->
</div>

<script>
function showTooltip(el, msg) {
if (!el.trigger.className.includes('tooltipped')) {
el.trigger.children[0].className = 'tooltipped tooltipped-s';
el.trigger.children[0].ariaLabel = msg;
}
}

window.onload = () => {
const clipboard = new ClipboardJS('.code-copy');
clipboard.on('success', (e) => showTooltip(e, 'Copied!'));
clipboard.on('error', (e) => showTooltip(e, 'Failed...'));
};
</script>
<script async src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.js"></script>
</body>
</html>

見やすさのために圧縮前のものを載せていますが、実際にはJavaScriptソースコード部分はUglifyJSで圧縮されたものになります。

導入方法

#

基本的にはプロジェクトのdevDependenciesへのプラグインインストールと、.eleventy.jsに以下を追加するだけで利用可能になります。
具体的な設定については、リポジトリのexampleを参照してください。

const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight');
const codeClipboard = require('eleventy-plugin-code-clipboard');
const markdownIt = require('markdown-it');

module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(syntaxHighlight); // 必須ライブラリ
eleventyConfig.addPlugin(codeClipboard); // プラグイン有効化

eleventyConfig.addPassthroughCopy('./src/css');

// その他の設定

/* Markdown Overrides */
const markdownLibrary = markdownIt({
html: true,
breaks: true,
}).use(codeClipboard.markdownItCopyButton); // プラグインのカスタムレンダラー設定

eleventyConfig.setLibrary('md', markdownLibrary);

return {
passthroughFileCopy: true,
dir: {
input: 'src',
},
};
};

上記の他にも、外部CSSライブラリ(アイコン/ツールチップ)のセットアップが必要になります。
詳しくは README を参照してください。

本サイト向けに作成したものをnpmパッケージ化しただけで、まだまだ汎用性が低いですが、時間を見つけて改善していきたいと思います。


  1. 現状は言語なしのコードブロックやIndented code blocks には対応していません。 ↩︎

豆蔵デベロッパーサイト - 先週のアクセスランキング
  1. 基本から理解するJWTとJWT認証の仕組み (2022-12-08)
  2. AWS認定資格を12個すべて取得したので勉強したことなどをまとめます (2022-12-12)
  3. Nuxt3入門(第4回) - Nuxtのルーティングを理解する (2022-10-09)
  4. Nuxt3入門(第1回) - Nuxtがサポートするレンダリングモードを理解する (2022-09-25)
  5. Nuxt3入門(第8回) - Nuxt3のuseStateでコンポーネント間で状態を共有する (2022-10-28)
  6. Jest再入門 - 関数・モジュールモック編 (2022-07-03)
  7. 自然言語処理初心者が「GPT2-japanese」で遊んでみた (2022-07-08)
  8. IoT を使ってみる(その6:MQTTブローカー Mosquitto編) (2022-10-08)
  9. Nuxt3入門(第3回) - ユニバーサルフェッチでデータを取得する (2022-10-06)
  10. 統計学で避けて通れない自由度の話 (2022-06-20)