プログラムでおかえしできるかな

Python、フェイジョア、日常のあれこれでお返し、元SEの隠居生活。

Markdownでもソースコードをコピーボタンでコピー

このエントリーをはてなブックマークに追加

Web ページ内のソースコードをコピーボタンでコピーする方法を解説します。
Web ページを Markdown 記法で記述している場合の方法です。

目次

Web サイトでプログラムのソースコードなどをコピーするボタンを時々見つけます。
コピーの対象は、プログラムのソースコード等です。
その実現方法を紹介するサイトはいくつか存在します。
しかし、Markdown 記法で上手く適用する内容のものは見つかりませんでした。
そこで、Markdown 記法で実装する方法について解説します。

◆文書をコピーボタンでコピーするための実装

はじめにこちらのサイトで紹介されていたテキストをコピーする方法を簡単に解説します。

参考にしたサイト:コピペで使える!JavaScriptでコピーボタンを作成する方法

【実装手順】

  • コピーしたい対象の文字列を含むタグに id を設定します
  • button タグを追加します
    onclick でクリックされた時に動作する関数を指定します
  • JavaScript で関数を作成します
    • getElementById() で指定した id を持つ要素を取得します
    • 取得した要素のテキストを navigator.clipboard.writeText() でクリップボードにコピーします

サンプルの HTML と JavaScript は次の通りです。
これは、「コピー内容」というテキストをクリップボードにコピーします。

▽HTML

<p id="copytxt">コピー内容</p>
<button onclick="copyButton ('copytxt')">コピー実行</button>
[フューチャースピリッツのエンジニアブログ](https://blog.future.ad.jp/)

※引用ですがオリジナルの誤りを修正してあります

▽JavaScript

function copyButton(elementId) {
            // 引数で得たIDの要素のテキストを取得
            var element = document.getElementById(elementId);
            // 上記要素をクリップボードにコピーする
            navigator.clipboard.writeText(element.textContent)
}
[フューチャースピリッツのエンジニアブログ](https://blog.future.ad.jp/)

◆Markdown でソースコードをコピーボタンでコピーするための実装

前述の対応内容に対して Markdown の場合に変更が必要な部分を説明します。

Markdown では、ソースコードを記述する場合、「```」で囲みます。
HTML に変換されると <pre> タグになります。
コピーしたいソースコードは <pre> タグに含まれます。
変換は自動的に実施されるので、<pre> タグに id を付加することはできません。

そこで、ソースコードを記述した場所の前に <div> タグで id を付加します。

<div> タグを追加した Markdown

   <div id="copytxt"></div>

   ```python
    ソースコード
   ```

これが HTML に変換されると次の様になります。

▽はてなブログのHTML(以後こちらに対応します)

<div id="copytxt"></div>
<pre class="code lang-html" data-lang="html" data-unlink="">ソースコード</pre>

▽Python-markdownのHTML

<div id="copytxt"></div>
<div> class="codehilite">
  <pre>ソースコード</pre>

その状態の HTML で先ほどの関数が動くようにします。
つまり、コピーするテキストが含まれるタグの見つけ方を変えます。

getElementById() では、id を設定したタグでないと見つかりません。
 (コピーしたいタグに id を付けなければならない)
そこで、ソースコードの前の <div> タグに id があり、次に <pre> タグがあるケースを探します。
それには、CSS セレクターを使います。
そして querySelector() なら CSS セレクターを使えます。
 (CSS セレクターについての詳細は省略します)

特定の id を持つタグとその兄弟の <pre> タグを持つ要素を捜します。

具体的には次のようにします。

▽CSS セレクターに対応した関数の一部

   document.querySelector('#' + elementId + '+ pre')

◆デモ

▽こちらでコードのコピーを試せます

from PIL import ImageTk
import tkinter as tk
import sys
root = tk.Tk()              # トップレベルウィンドウの作成
root.title("画像 viewer")   # タイトル
img = ImageTk.PhotoImage(file=sys.argv[1])  # 画像の読み込み コマンドライン引数の1番目のファイル名
tk.Label(root, image=img).pack()   # ラベルウィジェットの作成、画像指定
root.mainloop()

◆実装内容のまとめ

実装に使用したソースコードを以下にまとめます。

▽Markdown で書かれたソースコード部分

   <div id="copytxt"></div>

   ```python
    ソースコード
   ```
    <button onclick="copyButton ('copytxt')">コピー実行</button>

▽JavaScript

 <script>
    function copyButton(elementId) {
        /* 引数で得たIDの要素のテキストを取得 */
        var element = document.querySelector('#' + elementId + '+ pre');
        /* 上記要素をクリップボードにコピーする */
        navigator.clipboard.writeText(element.textContent)
        alert('コピーしました')
    }
    </script>

※はてなブログで動作します。
※コピーできるとダイアログを表示します。

◆さいごに

Markdown で記述している自分のブログにコピーボタンを追加しようと調べてみたら、みったり当てはまる例が見つかりませんでした。
プログラムのことはそこそこわかるし、最近は CSS セレクターにも触れる機会が多くなってきたので、何とかなりそうだと思い試してみました。
割とすぐできたので良かったです。

後はコピーボタンのデザインや表示位置をカスタマイズできるように、また勉強します。


あわせて読みたい 📖 はてなブログでMarkdown記法を使う 🔗

◇免責事項

ご利用に際しては、『免責事項』をご確認ください。
お気づきの点がございましたら『お問い合わせ』からお問い合わせください。

◆参考

投稿: