Skip to content

Commit 30197a0

Browse files
authored
Code snippets now contain a button copying the contents (#474)
Code snippets now contain one button for showing snippet sources and one for copying the contents This aligns the snippets with other doc tools that has a copy button up top right.
1 parent 534d7e3 commit 30197a0

File tree

18 files changed

+67
-41
lines changed

18 files changed

+67
-41
lines changed

core/src/main/scala/com/lightbend/paradox/markdown/StyledVerbatim.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ abstract class StyledVerbatimSerializer extends VerbatimSerializer {
4747

4848
node match {
4949
case vgn: VerbatimGroupNode =>
50+
printer.print("""<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button>""")
5051
vgn.getSourceUrl.ifPresent(new Consumer[String] {
51-
override def accept(sourceUrl: String): Unit =
52-
printer.print(s"""<a class="icon go-to-source" href="$sourceUrl" target="_blank" title="Go to snippet source"></a>""")
52+
override def accept(sourceUrl: String): Unit = {
53+
printer.print(s"""<a class="snippet-button go-to-source" href="$sourceUrl" target="_blank" title="Go to snippet source">source</a>""")
54+
}
5355
})
5456
case _ =>
5557
}

plugin/src/sbt-test/paradox/default-theme/expected/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<script type="text/javascript" src="js/page.js"></script>
1313
<script type="text/javascript" src="js/warnOldVersion.js"></script>
1414
<script type="text/javascript" src="js/groups.js"></script>
15+
<script type="text/javascript" src="js/snippets.js"></script>
1516
<link rel="stylesheet" type="text/css" href="lib/foundation/dist/foundation.min.css"/>
1617
<link rel="stylesheet" type="text/css" href="css/page.css"/>
1718

plugin/src/sbt-test/paradox/default-theme/expected/sub/indexed.html

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<script type="text/javascript" src="../js/page.js"></script>
1313
<script type="text/javascript" src="../js/warnOldVersion.js"></script>
1414
<script type="text/javascript" src="../js/groups.js"></script>
15+
<script type="text/javascript" src="../js/snippets.js"></script>
1516
<link rel="stylesheet" type="text/css" href="../lib/foundation/dist/foundation.min.css"/>
1617
<link rel="stylesheet" type="text/css" href="../css/page.css"/>
1718

plugin/src/sbt-test/paradox/default-theme/expected/sub/unindexed.html

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<script type="text/javascript" src="../js/page.js"></script>
1313
<script type="text/javascript" src="../js/warnOldVersion.js"></script>
1414
<script type="text/javascript" src="../js/groups.js"></script>
15+
<script type="text/javascript" src="../js/snippets.js"></script>
1516
<link rel="stylesheet" type="text/css" href="../lib/foundation/dist/foundation.min.css"/>
1617
<link rel="stylesheet" type="text/css" href="../css/page.css"/>
1718

Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<pre class="prettyprint"><code class="language-scala">val snippet = 0</code></pre>
1+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">val snippet = 0</code></pre>

plugin/src/sbt-test/paradox/snippet-noindent-writer/expected/index.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div>
22
<div>
3-
<pre class="prettyprint"><code class="language-scala">object Hello extends App {
3+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">object Hello extends App {
44
def say(str: String): Unit = {
55
println(str)
66
}
@@ -10,7 +10,7 @@
1010
</div>
1111
</div>
1212

13-
<pre class="prettyprint"><code class="language-scala">object Hello extends App {
13+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">object Hello extends App {
1414
def say(str: String): Unit = {
1515
println(str)
1616
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<pre class="prettyprint"><code class="language-scala">val foo = 42</code></pre>
2-
<pre class="prettyprint"><code class="language-scala">val foo = 42</code></pre>
3-
<pre class="prettyprint"><code class="language-scala">val foo = 42</code></pre>
4-
<pre class="prettyprint"><code class="language-scala">val foo = 42</code></pre>
1+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">val foo = 42</code></pre>
2+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">val foo = 42</code></pre>
3+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">val foo = 42</code></pre>
4+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">val foo = 42</code></pre>
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
<pre class="prettyprint group-a"><code class="language-scala">private class SomethingElse</code></pre>
2-
<pre class="prettyprint group-b"><code class="language-scala">import scala.util.Try</code></pre>
1+
<pre class="prettyprint group-a"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">private class SomethingElse</code></pre>
2+
<pre class="prettyprint group-b"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">import scala.util.Try</code></pre>

plugin/src/sbt-test/paradox/snippets/expected/multiple.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
<pre class="prettyprint"><code class="language-scala">import scala.concurrent.duration._
1+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">import scala.concurrent.duration._
22

33
case class Measurement(method: Method, duration: Duration)</code></pre>
4-
<pre class="prettyprint"><code class="language-scala">import scala.util.Try
4+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">import scala.util.Try
55

66
def parseInt(s: String): Option[Int] = Try(s.toInt).toOption</code></pre>
7-
<pre class="prettyprint"><code class="language-conf"># HTTP Configuration
7+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-conf"># HTTP Configuration
88
http {
99
port=80
1010
host=0.0.0.0

plugin/src/sbt-test/paradox/snippets/expected/nocode.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<pre class="prettyprint"><code class="nocode">certpath: -Using checker7 ... [sun.security.provider.certpath.RevocationChecker]
1+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="nocode">certpath: -Using checker7 ... [sun.security.provider.certpath.RevocationChecker]
22
certpath: connecting to OCSP service at: http://gtssl2-ocsp.geotrust.com
33
certpath: OCSP response status: SUCCESSFUL
44
certpath: OCSP response type: basic
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
<pre class="prettyprint"><code class="language-conf"># This should be included
1+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-conf"># This should be included
22
#and this as well
33

44
snippets {
55
# this snip is a snap
66
snip = &quot;snap&quot;
77
}</code></pre>
88
<!-- -->
9-
<pre class="prettyprint"><code class="language-conf"># this snip is a snap
9+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-conf"># this snip is a snap
1010
snip = &quot;snap&quot;</code></pre>
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
<pre class="prettyprint"><code class="language-scala">def indented = {
1+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">def indented = {
22
1 + 2
33
}</code></pre>
4-
<pre class="prettyprint"><code class="language-conf">snippets {
4+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-conf">snippets {
55
test = 1
66
}</code></pre>
7-
<pre class="prettyprint"><code class="language-scala">val symbols = Seq(&#39;symbols, Symbol(&quot;@&quot;), &#39;EOL)</code></pre>
8-
<pre class="prettyprint"><code class="language-scala">val spacy = &quot;Please do not remove ending spaces after these markers&quot;</code></pre>
7+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">val symbols = Seq(&#39;symbols, Symbol(&quot;@&quot;), &#39;EOL)</code></pre>
8+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">val spacy = &quot;Please do not remove ending spaces after these markers&quot;</code></pre>
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
<pre class="prettyprint"><code class="language-xml">&lt;bar&gt;
1+
<pre class="prettyprint"><button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-xml">&lt;bar&gt;
22
XML FTW
33
&lt;/bar&gt;</code></pre>

tests/src/test/scala/com/lightbend/paradox/markdown/IncludeDirectiveSpec.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class IncludeDirectiveSpec extends MarkdownBaseSpec {
5353
it should "include nested code snippets" in {
5454
markdown("""@@include(tests/src/test/resources/include-code-snip.md)""") shouldEqual html("""
5555
|<pre class="prettyprint">
56-
|<code class="language-conf">
56+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-conf">
5757
|a = b</code>
5858
|</pre>""")
5959
}

tests/src/test/scala/com/lightbend/paradox/markdown/SnipDirectiveSpec.scala

+13-13
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
3131
"The `snip` directive" should "render code snippets" in {
3232
markdown("""@@snip[example.scala](tests/src/test/scala/com/lightbend/paradox/markdown/example.scala) { #example }""") shouldEqual html("""
3333
|<pre class="prettyprint">
34-
|<code class="language-scala">
34+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">
3535
|object example extends App {
3636
| println("Hello, World!")
3737
|}</code>
@@ -50,7 +50,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
5050
|<dt>Scala</dt>
5151
|<dd>
5252
|<pre class="prettyprint">
53-
|<code class="language-scala">
53+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">
5454
|object example extends App {
5555
| println("Hello, World!")
5656
|}</code>
@@ -59,7 +59,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
5959
|<dt>Java</dt>
6060
|<dd>
6161
|<pre class="prettyprint">
62-
|<code class="language-java">
62+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-java">
6363
|public class example2 {
6464
| public static void main(String[] args) {
6565
| System.out.println("Hello, World");
@@ -75,7 +75,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
7575
|@@snip[example2.java](tests/src/test/scala/com/lightbend/paradox/markdown/example2.java){ #example2 .red .blue }
7676
|""") shouldEqual html("""
7777
|<pre class="prettyprint red blue">
78-
|<code class="language-java">
78+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-java">
7979
|public class example2 {
8080
| public static void main(String[] args) {
8181
| System.out.println("Hello, World");
@@ -87,7 +87,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
8787
it should "trim indentation from snippets" in {
8888
markdown("""@@snip[example.scala](tests/src/test/scala/com/lightbend/paradox/markdown/example.scala) { #indented-example }""") shouldEqual html("""
8989
|<pre class="prettyprint">
90-
|<code class="language-scala">
90+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">
9191
|case object Dent
9292
| case object DoubleDent</code>
9393
|</pre>""")
@@ -96,7 +96,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
9696
it should "not truncate snippets" in {
9797
markdown("""@@snip[example.scala](tests/src/test/scala/com/lightbend/paradox/markdown/example.scala) { #multi-indented-example }""") shouldEqual html("""
9898
|<pre class="prettyprint">
99-
|<code class="language-scala">
99+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">
100100
|object AnotherIndentedExample {
101101
| def rendered(): Unit = {
102102
| }
@@ -106,15 +106,15 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
106106
|</pre>""")
107107
}
108108

109-
it should "add link to source" in {
109+
it should "add link to source and copy button" in {
110110
implicit val context = writerContextWithProperties(
111111
"github.base_url" -> "https://github.com/lightbend/paradox/tree/v0.2.1",
112112
"github.root.base_dir" -> new File(".").getAbsoluteFile.getParent,
113113
"snip.github_link" -> "true")
114114

115115
markdown("""@@snip[example.scala](tests/src/test/scala/com/lightbend/paradox/markdown/example.scala) { #example }""") shouldEqual html(
116116
"""<pre class="prettyprint">
117-
|<a class="icon go-to-source" href="https://github.com/lightbend/paradox/tree/v0.2.1/tests/src/test/scala/com/lightbend/paradox/markdown/example.scala#L28-L30" target="_blank" title="Go to snippet source"></a><code class="language-scala">
117+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><a class="snippet-button go-to-source" href="https://github.com/lightbend/paradox/tree/v0.2.1/tests/src/test/scala/com/lightbend/paradox/markdown/example.scala#L28-L30" target="_blank" title="Go to snippet source">source</a><code class="language-scala">
118118
|object example extends App {
119119
| println("Hello, World!")
120120
|}</code>
@@ -131,7 +131,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
131131

132132
markdown("""@@snip[example.scala]($test$/example.scala) { #example }""") shouldEqual html(
133133
"""<pre class="prettyprint">
134-
|<a class="icon go-to-source" href="https://github.com/lightbend/paradox/tree/v0.2.1/tests/src/test/scala/com/lightbend/paradox/markdown/example.scala#L28-L30" target="_blank" title="Go to snippet source"></a><code class="language-scala">
134+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><a class="snippet-button go-to-source" href="https://github.com/lightbend/paradox/tree/v0.2.1/tests/src/test/scala/com/lightbend/paradox/markdown/example.scala#L28-L30" target="_blank" title="Go to snippet source">source</a><code class="language-scala">
135135
|object example extends App {
136136
| println("Hello, World!")
137137
|}</code>
@@ -147,7 +147,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
147147

148148
markdown("""@@snip[example.scala](tests/src/test/scala/com/lightbend/paradox/markdown/example.scala) { #example }""") shouldEqual html(
149149
"""<pre class="prettyprint">
150-
|<code class="language-scala">
150+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">
151151
|object example extends App {
152152
| println("Hello, World!")
153153
|}</code>
@@ -157,7 +157,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
157157
it should "include labels when including the whole file" in {
158158
markdown("""@@snip[example.scala](tests/src/test/scala/com/lightbend/paradox/markdown/example.scala)""") shouldEqual html(
159159
"""<pre class="prettyprint">
160-
|<code class="language-scala">
160+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">
161161
|/*
162162
| * Copyright &copy; 2015 - 2019 Lightbend, Inc. &lt;http://www.lightbend.com&gt;
163163
| *
@@ -247,7 +247,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
247247
it should "filter labels by default" in {
248248
markdown("""@@snip[example.scala](tests/src/test/scala/com/lightbend/paradox/markdown/example.scala) { #example-with-label }""") shouldEqual html(
249249
"""<pre class="prettyprint">
250-
|<code class="language-scala">
250+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">
251251
|object Constants {
252252
|}</code>
253253
|</pre>"""
@@ -257,7 +257,7 @@ class SnipDirectiveSpec extends MarkdownBaseSpec {
257257
it should "allow including labels if specified" in {
258258
markdown("""@@snip[example.scala](tests/src/test/scala/com/lightbend/paradox/markdown/example.scala) { #example-with-label filterLabels=false }""") shouldEqual html(
259259
"""<pre class="prettyprint">
260-
|<code class="language-scala">
260+
|<button class="snippet-button copy-snippet" title="Copy snippet to clipboard">copy</button><code class="language-scala">
261261
|object Constants {
262262
| val someString = " #foo "
263263
|}</code>

themes/generic/src/main/assets/css/page.css

+19-5
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,29 @@ a.anchor .anchor-link:before {
149149
content: "§";
150150
}
151151

152-
a.go-to-source::before {
153-
content: "📄";
152+
.site-content .page-content .prettyprint .snippet-button {
153+
float: right;
154+
text-decoration: none;
155+
font-size: 0.75rem;
156+
font-weight: bold;
157+
font-family: "Roboto", "Helvetica Neue", "Helvetica", Arial, sans-serif;
158+
speak: none;
159+
color: #4078c0;
160+
border: 2px solid #e5e6e4;
161+
padding: 4px 4px;
162+
margin-left: 8px;
163+
line-height: 1.2;
164+
vertical-align: middle;
165+
-webkit-font-smoothing: antialiased;
166+
-moz-osx-font-smoothing: grayscale;
154167
}
155168

156-
.prettyprint .icon {
157-
float: right;
169+
.site-content .page-content .prettyprint .snippet-button:hover {
170+
background-color: #e5e6e4;
171+
border: 2px solid #4078c0;
158172
}
159173

160-
a.anchor .anchor-link, .icon {
174+
a.anchor .anchor-link {
161175
font-size: 18px;
162176
font-family: "icons" !important;
163177
font-style: normal !important;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
$(function() {
2+
$(".snippet-button.copy-snippet").click(function() {
3+
var code = $(this).parent().find("code").text()
4+
navigator.clipboard.writeText(code)
5+
})
6+
})

themes/generic/src/main/assets/page.st

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ $endif$
1414
<script type="text/javascript" src="$page.base$js/page.js"></script>
1515
<script type="text/javascript" src="$page.base$js/warnOldVersion.js"></script>
1616
<script type="text/javascript" src="$page.base$js/groups.js"></script>
17+
<script type="text/javascript" src="$page.base$js/snippets.js"></script>
1718
<link rel="stylesheet" type="text/css" href="$page.base$lib/foundation/dist/foundation.min.css"/>
1819
<link rel="stylesheet" type="text/css" href="$page.base$css/page.css"/>
1920

0 commit comments

Comments
 (0)