diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
new file mode 100644
index 000000000..ec63ab98b
--- /dev/null
+++ b/buildSrc/build.gradle
@@ -0,0 +1,7 @@
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile 'org.asciidoctor:asciidoctorj:1.5.2'
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/groovy/org/springframework/restdocs/asciidoctor/CodeBlockSwitchExtension.groovy b/buildSrc/src/main/groovy/org/springframework/restdocs/asciidoctor/CodeBlockSwitchExtension.groovy
new file mode 100644
index 000000000..2dbd03649
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/springframework/restdocs/asciidoctor/CodeBlockSwitchExtension.groovy
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2014-2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.restdocs.asciidoctor
+
+import org.asciidoctor.Asciidoctor
+import org.asciidoctor.extension.spi.ExtensionRegistry
+
+class CodeBlockSwitchExtension implements ExtensionRegistry {
+
+ @Override
+ public void register(Asciidoctor asciidoctor) {
+ asciidoctor.javaExtensionRegistry().postprocessor(new CodeBlockSwitchPostProcessor());
+ }
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/groovy/org/springframework/restdocs/asciidoctor/CodeBlockSwitchPostProcessor.groovy b/buildSrc/src/main/groovy/org/springframework/restdocs/asciidoctor/CodeBlockSwitchPostProcessor.groovy
new file mode 100644
index 000000000..e87edf966
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/springframework/restdocs/asciidoctor/CodeBlockSwitchPostProcessor.groovy
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2014-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.restdocs.asciidoctor
+
+import org.asciidoctor.ast.Document
+import org.asciidoctor.extension.Postprocessor
+
+class CodeBlockSwitchPostProcessor extends Postprocessor {
+
+ String process(Document document, String output) {
+ def css = getClass().getResource("/codeBlockSwitch.css").text
+ def javascript = getClass().getResource("/codeBlockSwitch.js").text
+ def replacement = """
+
+
+
+"""
+ return output.replace("", replacement);
+ }
+
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/resources/META-INF/services/org.asciidoctor.extension.spi.ExtensionRegistry b/buildSrc/src/main/resources/META-INF/services/org.asciidoctor.extension.spi.ExtensionRegistry
new file mode 100644
index 000000000..2dcc8a1d3
--- /dev/null
+++ b/buildSrc/src/main/resources/META-INF/services/org.asciidoctor.extension.spi.ExtensionRegistry
@@ -0,0 +1 @@
+org.springframework.restdocs.asciidoctor.CodeBlockSwitchExtension
\ No newline at end of file
diff --git a/buildSrc/src/main/resources/codeBlockSwitch.css b/buildSrc/src/main/resources/codeBlockSwitch.css
new file mode 100644
index 000000000..6fb1947b1
--- /dev/null
+++ b/buildSrc/src/main/resources/codeBlockSwitch.css
@@ -0,0 +1,23 @@
+.hidden {
+ display: none;
+}
+
+.switch {
+ border-width: 1px 1px 0 1px;
+ border-style: solid;
+ border-color: #7a2518;
+ display: inline-block;
+}
+
+.switch--item {
+ padding: 10px;
+ background-color: #ffffff;
+ color: #7a2518;
+ display: inline-block;
+ cursor: pointer;
+}
+
+.switch--item.selected {
+ background-color: #7a2519;
+ color: #ffffff;
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/resources/codeBlockSwitch.js b/buildSrc/src/main/resources/codeBlockSwitch.js
new file mode 100644
index 000000000..13ac0fc1e
--- /dev/null
+++ b/buildSrc/src/main/resources/codeBlockSwitch.js
@@ -0,0 +1,45 @@
+function addBlockSwitches() {
+ $('.primary').each(function() {
+ primary = $(this);
+ createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
+ primary.children('.title').remove();
+ });
+ $('.secondary').each(function(idx, node) {
+ secondary = $(node);
+ primary = findPrimary(secondary);
+ switchItem = createSwitchItem(secondary, primary.children('.switch'));
+ switchItem.content.addClass('hidden');
+ findPrimary(secondary).append(switchItem.content);
+ secondary.remove();
+ });
+}
+
+function createBlockSwitch(primary) {
+ blockSwitch = $('
');
+ primary.prepend(blockSwitch);
+ return blockSwitch;
+}
+
+function findPrimary(secondary) {
+ candidate = secondary.prev();
+ while (!candidate.is('.primary')) {
+ candidate = candidate.prev();
+ }
+ return candidate;
+}
+
+function createSwitchItem(block, blockSwitch) {
+ blockName = block.children('.title').text();
+ content = block.children('.content').first().append(block.next('.colist'));
+ item = $('' + blockName + '
');
+ item.on('click', '', content, function(e) {
+ $(this).addClass('selected');
+ $(this).siblings().removeClass('selected');
+ e.data.siblings('.content').addClass('hidden');
+ e.data.removeClass('hidden');
+ });
+ blockSwitch.append(item);
+ return {'item': item, 'content': content};
+}
+
+$(addBlockSwitches);
\ No newline at end of file
diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc
index 6a652de67..ccc0f7a59 100644
--- a/docs/src/docs/asciidoc/getting-started.adoc
+++ b/docs/src/docs/asciidoc/getting-started.adoc
@@ -28,82 +28,14 @@ The code that produces the generated snippets can be found in `src/test/java`.
[[getting-started-build-configuration]]
=== Build configuration
-The first step in using Spring REST Docs is to configure your project's build.
-
-
-
-[[getting-started-build-configuration-gradle]]
-==== Gradle build configuration
-
-The {samples}/rest-notes-spring-hateoas[Spring HATEOAS sample] contains a `build.gradle`
-file that you may wish to use as a reference. The key parts of the configuration are
-described below.
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- plugins { <1>
- id "org.asciidoctor.convert" version "1.5.2"
- }
-
- dependencies { <2>
- testCompile 'org.springframework.restdocs:spring-restdocs-mockmvc:{project-version}'
- }
-
- ext { <3>
- snippetsDir = file('build/generated-snippets')
- }
-
- test { <4>
- outputs.dir snippetsDir
- }
-
- asciidoctor { <5>
- attributes 'snippets': snippetsDir <6>
- inputs.dir snippetsDir <7>
- dependsOn test <8>
- }
-----
-<1> Apply the Asciidoctor plugin.
-<2> Add a dependency on `spring-restdocs-mockmvc` in the `testCompile` configuration.
-<3> Configure a property to define the output location for generated snippets.
-<4> Configure the `test` task to add the snippets directory as an output.
-<5> Configure the `asciidoctor` task
-<6> Define an attribute named `snippets` that can be used when including the generated
- snippets in your documentation.
-<7> Configure the snippets directory as an input.
-<8> Make the task depend on the test task so that the tests are run before the
- documentation is created.
-
-
-[[getting-started-build-configuration-gradle-packaging-the-documentation]]
-==== Packaging the documentation
-
-You may want to package the generated documentation in your project's jar file, for
-example to have it {spring-boot-docs}/#boot-features-spring-mvc-static-content[served as
-static content] by Spring Boot. You can do so by configuring the `jar` task to depend on
-the `asciidoctor` task and to copy the generated documentation into the jar's static
-directory:
-
-[source,groovy,indent=0]
-----
- jar {
- dependsOn asciidoctor
- from ("${asciidoctor.outputDir}/html5") {
- into 'static/docs'
- }
- }
-----
-
-
-
-[[getting-started-build-configuration-maven]]
-==== Maven build configuration
-
-The {samples}/rest-notes-spring-data-rest[Spring Data REST sample] contains a `pom.xml`
-file that you may wish to use as a reference. The key parts of the configuration are
-described below.
-
-[source,xml,indent=0,subs="verbatim,attributes"]
+The first step in using Spring REST Docs is to configure your project's build. The
+{samples}/rest-notes-spring-hateoas[Spring HATEOAS] and
+{samples}/rest-notes-spring-data-rest[Spring Data REST] samples contain a `build.gradle`
+and `pom.xml` respectively that you may wish to use as a reference. The key parts of
+the configuration are described below.
+
+[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
+.Maven
----
<1>
org.springframework.restdocs
@@ -150,7 +82,6 @@ described below.
-
----
<1> Add a dependency on `spring-restdocs-mockmvc` in the `test` scope.
<2> Configure a property to define the output location for generated snippets.
@@ -163,19 +94,55 @@ described below.
<> in your
project's jar you should use the `prepare-package` phase.
-[[getting-started-build-configuration-maven-packaging]]
+[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
+.Gradle
+----
+ plugins { <1>
+ id "org.asciidoctor.convert" version "1.5.2"
+ }
+
+ dependencies { <2>
+ testCompile 'org.springframework.restdocs:spring-restdocs-mockmvc:{project-version}'
+ }
+
+ ext { <3>
+ snippetsDir = file('build/generated-snippets')
+ }
+
+ test { <4>
+ outputs.dir snippetsDir
+ }
+
+ asciidoctor { <5>
+ attributes 'snippets': snippetsDir <6>
+ inputs.dir snippetsDir <7>
+ dependsOn test <8>
+ }
+----
+<1> Apply the Asciidoctor plugin.
+<2> Add a dependency on `spring-restdocs-mockmvc` in the `testCompile` configuration.
+<3> Configure a property to define the output location for generated snippets.
+<4> Configure the `test` task to add the snippets directory as an output.
+<5> Configure the `asciidoctor` task
+<6> Define an attribute named `snippets` that can be used when including the generated
+ snippets in your documentation.
+<7> Configure the snippets directory as an input.
+<8> Make the task depend on the test task so that the tests are run before the
+ documentation is created.
+
+
+[[getting-started-build-configuration-gradle-packaging-the-documentation]]
==== Packaging the documentation
You may want to package the generated documentation in your project's jar file, for
example to have it {spring-boot-docs}/#boot-features-spring-mvc-static-content[served as
-static content] by Spring Boot.
+static content] by Spring Boot. To do so, configure your project's build so that:
-First, configure the Asciidoctor plugin so that it runs in the `prepare-package` phase, as
-<>. Now configure
-Maven's resources plugin to copy the generated documentation into a location where it'll
-be included in the project's jar:
+1. The documentation is generated before the jar is built
+2. The generated documentation is included in the jar
-[source,xml,indent=0]
+[source,xml,indent=0,role="primary",role="primary"]
+.Maven
----
<1>
org.asciidoctor
@@ -192,7 +159,7 @@ be included in the project's jar:
copy-resources
-
+ <3>
${project.build.outputDirectory}/static/docs
@@ -211,7 +178,22 @@ be included in the project's jar:
<1> The existing declaration for the Asciidoctor plugin.
<2> The resource plugin must be declared after the Asciidoctor plugin as they are bound
to the same phase (`prepare-package`) and the resource plugin must run after the
-Asciidoctor plugin.
+Asciidoctor plugin to ensure that the documentation is generated before it's copied.
+<3> Copy the generated documentation into the build output's `static/docs` directory,
+from where it will be included in the jar file.
+
+[source,groovy,indent=0,role="secondary"]
+.Gradle
+----
+ jar {
+ dependsOn asciidoctor <1>
+ from ("${asciidoctor.outputDir}/html5") { <2>
+ into 'static/docs'
+ }
+ }
+----
+<1> Ensure that the documentation has been generated before the jar is built.
+<2> Copy the generated documentation into the jar's `static/docs` directory.