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.