Skip to content

Commit 8470860

Browse files
ammarnajjarasottile
authored andcommitted
feat: add copy-icon top-left all code-blocks
Issue: #330
1 parent 5cc94b4 commit 8470860

File tree

8 files changed

+77
-8
lines changed

8 files changed

+77
-8
lines changed

.pre-commit-config.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ repos:
2929
hooks:
3030
- id: mypy
3131
exclude: ^install-local.py$
32+
- repo: https://github.com/pre-commit/mirrors-eslint
33+
rev: v7.0.0-alpha.3
34+
hooks:
35+
- id: eslint
36+
args: [--fix]
3237
- repo: local
3338
hooks:
3439
- id: scss-lint

assets/copy-icon.svg

Lines changed: 1 addition & 0 deletions
Loading

assets/copyable.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
(function () {
2+
function copyTextToClipboard(text) {
3+
var textArea = document.createElement('textarea');
4+
textArea.value = text;
5+
textArea.style.position = 'fixed';
6+
textArea.style.left = '-1';
7+
textArea.style.top = '-1';
8+
document.body.appendChild(textArea);
9+
textArea.focus();
10+
textArea.select();
11+
document.execCommand('copy');
12+
document.body.removeChild(textArea);
13+
}
14+
var codeBlockElements = document.getElementsByClassName('copyable');
15+
for (var i = 0; i < codeBlockElements.length; i++) {
16+
var block = codeBlockElements[i];
17+
var copyIcon = new Image(16, 16);
18+
copyIcon.setAttribute('src', './assets/copy-icon.svg');
19+
copyIcon.setAttribute('alt', 'copy');
20+
copyIcon.setAttribute('title', 'copy to clipboard');
21+
block.insertBefore(copyIcon, block.children[0]);
22+
copyIcon.addEventListener('click', function(block) {
23+
var text = block.getElementsByTagName('pre')[0].innerText;
24+
copyTextToClipboard(text);
25+
}.bind(null, block));
26+
}
27+
})();

base.mako

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,6 @@
6868
ga('create', 'UA-104682927-1', 'auto');
6969
ga('send', 'pageview');
7070
</script>
71+
<script src="assets/copyable.js"></script>
7172
</body>
7273
</html>

index.mako

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,27 +1501,27 @@ you use pre-commit!
15011501
15021502
- Markdown:
15031503
1504-
```md
1504+
```md#copyable
15051505
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
15061506
```
15071507
15081508
- HTML:
15091509
1510-
```html
1510+
```html#copyable
15111511
<a href="https://github.com/pre-commit/pre-commit"><img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white" alt="pre-commit" style="max-width:100%;"></a>
15121512
```
15131513
15141514
- reStructuredText:
15151515
1516-
```rst
1516+
```rst#copyable
15171517
.. image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white
15181518
:target: https://github.com/pre-commit/pre-commit
15191519
:alt: pre-commit
15201520
```
15211521
15221522
- AsciiDoc:
15231523
1524-
```
1524+
```#copyable
15251525
image:https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white[pre-commit, link=https://github.com/pre-commit/pre-commit]
15261526
```
15271527

package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,28 @@
33
"license": "MIT",
44
"dependencies": {
55
"bootstrap-sass": "3.4.1"
6+
},
7+
"eslintConfig": {
8+
"extends": "eslint:recommended",
9+
"rules": {
10+
"indent": [
11+
"error",
12+
4
13+
],
14+
"quotes": [
15+
"error",
16+
"single"
17+
],
18+
"semi": [
19+
"error",
20+
"always"
21+
]
22+
},
23+
"parserOptions": {
24+
"ecmaVersion": 6
25+
},
26+
"env": {
27+
"browser": true
28+
}
629
}
730
}

scss/main.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ h1,
202202
.s2 { color: #8ae234; }
203203
}
204204

205+
.copyable img { cursor: pointer; }
206+
205207
@media (max-width: $screen-md-max) {
206208
.table-bordered td:first-child {
207209
background: #f5f5f5;

template_lib.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import shlex
44
import subprocess
55
import sys
6+
from typing import Optional
67

78
import markdown_code_blocks
89
import markupsafe
@@ -99,13 +100,22 @@ def header(self, text: str, level: int, raw: str) -> str:
99100
f'</h{level}> '
100101
)
101102

102-
def block_code(self, code: str, lang: str) -> str:
103+
def block_code(self, code: str, lang: Optional[str]) -> str:
104+
copyable = False
105+
if lang is not None:
106+
copyable_s = '#copyable'
107+
copyable = lang.endswith(copyable_s)
108+
lang, _, _ = lang.partition(copyable_s)
103109
if lang == 'table':
104-
return _render_table(code)
110+
ret = _render_table(code)
105111
elif lang == 'cmd':
106-
return _render_cmd(code)
112+
ret = _render_cmd(code)
107113
else:
108-
return super().block_code(code, lang)
114+
ret = super().block_code(code, lang)
115+
if copyable:
116+
return f'<div class="copyable">{ret}</div>'
117+
else:
118+
return ret
109119

110120

111121
def md(s: str) -> str:

0 commit comments

Comments
 (0)