操作

第 1 步,在 _includes 添加如下文件:

  • plantuml.liquid: The main parser to generate the PlantUML diagrams
  • capturehtml.liquid: Un-escapes HTML special characters, used to parse HTML tags inside pre-formatted code blocks

第 2 步,在 _layouts/post.html 文件添加如下内容:


<!-- Some other stuff... -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.11/pako.min.js" integrity="sha512-euWc/Qv8Kp0CbTX1M+Q3BvUyoOaq9Au50TT7vz3MFf5ver39ybq6zV+RngDY8eN8AIQFigxjwYv6jhoP546vfQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
  // Adapted from
  // https://github.com/markushedvall/plantuml-encoder/blob/master/lib/encode64.js
  function encodeToPlantumlEncoded(text) {
    function encodeFromB64(c) {
      const i = "=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(c)
      return "00123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".at(i) || "?"
    }

    return [...btoa(text)].map(encodeFromB64).join("")
  }
</script>
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">

  <header class="post-header">
    <h1 class="post-title p-name" itemprop="name headline">Copy to Clipboard</h1>
    <p class="post-meta">
      <time class="dt-published" datetime="2025-01-14T14:18:06+00:00" itemprop="datePublished">Jan 14, 2025
      </time></p>
  </header>

  <div class="post-content e-content" itemprop="articleBody">
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.11/pako.min.js" integrity="sha512-euWc/Qv8Kp0CbTX1M+Q3BvUyoOaq9Au50TT7vz3MFf5ver39ybq6zV+RngDY8eN8AIQFigxjwYv6jhoP546vfQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
  // Adapted from
  // https://github.com/markushedvall/plantuml-encoder/blob/master/lib/encode64.js
  function encodeToPlantumlEncoded(text) {
    function encodeFromB64(c) {
      const i = "=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(c)
      return "00123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".at(i) || "?"
    }

    return [...btoa(text)].map(encodeFromB64).join("")
  }
</script>
<h2 id="步骤">步骤</h2>

<p>第 1 步,添加 <code class="language-plaintext highlighter-rouge">assets/js/copyCode.js</code> 文件:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">codeBlocks</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelectorAll</span><span class="p">(</span><span class="dl">'</span><span class="s1">pre.highlight</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">codeBlocks</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">codeBlock</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">copyButton</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">button</span><span class="dl">'</span><span class="p">);</span>
    <span class="nx">copyButton</span><span class="p">.</span><span class="nx">className</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">copy</span><span class="dl">'</span><span class="p">;</span>
    <span class="nx">copyButton</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">button</span><span class="dl">'</span><span class="p">;</span>
    <span class="nx">copyButton</span><span class="p">.</span><span class="nx">ariaLabel</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Copy code to clipboard</span><span class="dl">'</span><span class="p">;</span>
    <span class="nx">copyButton</span><span class="p">.</span><span class="nx">innerText</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Copy</span><span class="dl">'</span><span class="p">;</span>
    <span class="nx">codeBlock</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">copyButton</span><span class="p">);</span>
    <span class="nx">copyButton</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">code</span> <span class="o">=</span> <span class="nx">codeBlock</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">code</span><span class="dl">'</span><span class="p">).</span><span class="nx">innerText</span><span class="p">.</span><span class="nx">trim</span><span class="p">();</span>
        <span class="nb">window</span><span class="p">.</span><span class="nb">navigator</span><span class="p">.</span><span class="nx">clipboard</span><span class="p">.</span><span class="nx">writeText</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span>
        <span class="nx">copyButton</span><span class="p">.</span><span class="nx">innerText</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Copied</span><span class="dl">'</span><span class="p">;</span>
        <span class="kd">const</span> <span class="nx">fourSeconds</span> <span class="o">=</span> <span class="mi">4000</span><span class="p">;</span>
        <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
            <span class="nx">copyButton</span><span class="p">.</span><span class="nx">innerText</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Copy</span><span class="dl">'</span><span class="p">;</span>
        <span class="p">},</span> <span class="nx">fourSeconds</span><span class="p">);</span>
    <span class="p">});</span>
<span class="p">});</span>
</code></pre></div></div>

<p>第 2 步,引入 HTML 页面:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;script src="/assets/js/copyCode.js"&gt;&lt;/script&gt;
</code></pre></div></div>

<p>例如,在 <code class="language-plaintext highlighter-rouge">_includes/head.html</code> 文件添加:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;script type="text/javascript" src="/assets/js/copyCode.js" defer&gt;&lt;/script&gt;
</code></pre></div></div>

<p>第 3 步,修改样式(非必要),例如添加在 <code class="language-plaintext highlighter-rouge">assets/css/extra.css</code> 文件:</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">pre</span><span class="nc">.highlight</span> <span class="p">{</span>
    <span class="nl">padding</span><span class="p">:</span> <span class="m">8px</span> <span class="m">12px</span><span class="p">;</span>
    <span class="nl">position</span><span class="p">:</span> <span class="nb">relative</span><span class="p">;</span>

    <span class="cm">/* Override skeleton styles */</span>

    <span class="o">&gt;</span> <span class="nt">code</span> <span class="p">{</span>
        <span class="nl">border</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span>
        <span class="nl">overflow-x</span><span class="p">:</span> <span class="nb">auto</span><span class="p">;</span>
        <span class="nl">padding-right</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span>
        <span class="nl">padding-left</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">&amp;</span><span class="nc">.highlight</span> <span class="p">{</span>
        <span class="nl">border-left</span><span class="p">:</span> <span class="m">15px</span> <span class="nb">solid</span> <span class="mh">#35383c</span><span class="p">;</span>
        <span class="nl">color</span><span class="p">:</span> <span class="mh">#c1c2c3</span><span class="p">;</span>
        <span class="nl">overflow</span><span class="p">:</span> <span class="nb">auto</span><span class="p">;</span>
        <span class="nl">white-space</span><span class="p">:</span> <span class="n">pre</span><span class="p">;</span>
        <span class="nl">word-wrap</span><span class="p">:</span> <span class="nb">normal</span><span class="p">;</span>

        <span class="k">&amp;</span><span class="o">,</span> <span class="nt">code</span> <span class="p">{</span>
            <span class="nl">background-color</span><span class="p">:</span> <span class="mh">#222</span><span class="p">;</span>
            <span class="nl">font-size</span><span class="p">:</span> <span class="m">14px</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="cm">/* Copy code to clipboard button */</span>

    <span class="nc">.copy</span> <span class="p">{</span>
        <span class="nl">color</span><span class="p">:</span> <span class="mh">#4AF626</span><span class="p">;</span>
        <span class="nl">position</span><span class="p">:</span> <span class="nb">absolute</span><span class="p">;</span>
        <span class="nl">right</span><span class="p">:</span> <span class="m">1</span><span class="mi">.2rem</span><span class="p">;</span>
        <span class="nl">top</span><span class="p">:</span> <span class="m">1</span><span class="mi">.2rem</span><span class="p">;</span>
        <span class="nl">opacity</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span>

        <span class="k">&amp;</span><span class="nd">:active</span><span class="o">,</span>
        <span class="k">&amp;</span><span class="nd">:focus</span><span class="o">,</span>
        <span class="k">&amp;</span><span class="nd">:hover</span> <span class="p">{</span>
            <span class="nl">background</span><span class="p">:</span> <span class="nf">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span> <span class="m">0</span><span class="o">,</span> <span class="m">0</span><span class="o">,</span> <span class="m">0</span><span class="mi">.5</span><span class="p">);</span>
            <span class="nl">opacity</span><span class="p">:</span> <span class="m">1</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">&amp;</span><span class="nd">:active</span> <span class="nc">.copy</span><span class="o">,</span>
    <span class="k">&amp;</span><span class="nd">:focus</span> <span class="nc">.copy</span><span class="o">,</span>
    <span class="k">&amp;</span><span class="nd">:hover</span> <span class="nc">.copy</span> <span class="p">{</span>
        <span class="nl">background</span><span class="p">:</span> <span class="nf">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span> <span class="m">0</span><span class="o">,</span> <span class="m">0</span><span class="o">,</span> <span class="m">0</span><span class="mi">.7</span><span class="p">);</span>
        <span class="nl">opacity</span><span class="p">:</span> <span class="m">1</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="reference">Reference</h2>

<ul>
  <li><a href="https://www.reddit.com/r/web_design/comments/t9nkmq/easiest_way_to_place_copy_to_clipboard_on_a/">Easiest way to place “Copy to Clipboard” on a Jekyll Blog</a></li>
</ul>
  </div><a class="u-url" href="/jekyll/jekyll-copy-to-clipboard.html" hidden></a>
</article>

<div id="toc_div" class="w3-card" style="position:fixed;padding:7px;bottom:50px;left:0;max-width:450px;z-index:999;display:none;">
        <span onclick="document.getElementById('toc_div').style.display='none'"
              class="w3-button w3-display-topright">&times;</span>
  <div class="at">
    <!-- at == auto table of content -->
    <!-- https://www.jqueryscript.net/menu/TOC-Generator-Smooth-Scroll-autoToc.html -->
  </div>
  <span onclick="document.getElementById('toc_div').style.display='none'"
        class="w3-button w3-display-bottomleft" style="font-size: 10px">CLOSE</span>
</div>
<div class="w3-clear"></div>

第 3 步,使用:

```plantuml
Alice -> Bob: Hi there!
Bob --> Alice: Hello to you too!
```

Reference