Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jekyll Code snippet copy-to-clipboard button

The Problem

I am building a Jekyll site with the minima theme to publish some tutorial online. The tutorial pages contain many code snippets, for example:

```javascript
/* Global scope: this code is executed once */
const redis = require('redis');

const host = <HOSTNAME>;
const port = <PORT>;
const password = <PASSWORD>;

...
```

I would like to add a "copy to clipboard" button to each code snippet (example), but not sure what's the right way to do it in Jekyll.

What have I tried

  • Using clipboardjs.com. It requires a unique ID for each snippet, and I'm not sure how to implement this in Jekyll/Markdown.
  • STFW

My question

How can I add a "Copy to Clipboard" button for code snippets in Jekyll?

like image 227
Adam Matan Avatar asked Jan 03 '18 13:01

Adam Matan


People also ask

How do I add a copy button in markdown?

To create this copy button, we need to append a button to each code block and have that button copy the code into the clipboard when clicked.

How do I insert a code block in Markdown?

To produce a code block in Markdown, simply indent every line of the block by at least 4 spaces or 1 tab. For example, given this input: This is a normal paragraph: This is a code block. A code block continues until it reaches a line that is not indented (or the end of the article).


1 Answers

Manually generate id's for each block of code with kramdown's Block Inline Attribute Lists, adding {: #code-example-1} after it.

In your example:

```javascript
/* Global scope: this code is executed once */
const redis = require('redis');

const host = <HOSTNAME>;
const port = <PORT>;
const password = <PASSWORD>;

...
```
{: #code-example-1}

That will generate:

<div id="code-example-1" class="language-javascript highlighter-rouge">
....
</div>

using jquery

Code blocks use thecode html element, if we detect it, then we load the js, traverse all code elements adding a custom id, and a button to copy their content. Finally initialize the Clipboard buttons.

{% if page.content contains "code" %}
<script>
<!-- clipboard.js code -->
</script>
{% endif %}

// get all <code> elements
var allCodeBlocksElements = $( "code" );

allCodeBlocksElements.each(function(i) {
 	// add different id for each code block

	// target	
  var currentId = "codeblock" + (i + 1);
  $(this).attr('id', currentId);
     
  //trigger
  var clipButton = '<button class="btn" data-clipboard-target="#' + currentId + '"><img src="https://clipboardjs.com/assets/images/clippy.svg" width="13" alt="Copy to clipboard"></button>';
     $(this).after(clipButton);
  });
 
  new Clipboard('.btn');
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/clipboard@1/dist/clipboard.min.js"></script>


<code>print("Club Nacional de Football")</code>
<br>
<code>print("is a sports institution")</code>
<br>
<code>print("from Uruguay")</code>
like image 181
marcanuy Avatar answered Sep 21 '22 17:09

marcanuy